kill
kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Signals table 을 보면 알 수 있겠지만 대부분의 신호들은 치명적인 오류를 나타내고 default action 으로 프로세스가 종료됩니다. 그러므로 왜 신호를 보내는 명령 이름이 kill 인지 짐작을 할 수 있습니다. kill 명령으로 신호를 보낼때 신호값을 주지 않으면 기본값 또한 TERM 신호가 됩니다.
다음은 kill 명령 사용 예입니다. 신호명 앞에 SIG 를 제외하고 사용할 수 있고 소문자로 쓸 수도 있습니다. 또한 pid 대신에 jobspec 을 사용할 수 있습니다.
kill -TERM 4287
kill -SIGTERM 4287
kill -s TERM 4287
kill -s SIGTERM 4287
kill -n 15 4287
kill -15 4287
kill 4287 # 신호값을 주지 않으면 기본값은 TERM 신호가 된다.
kill 신호값 -PGID
kill 명령을 이용해 process group 에 신호를 보낼 수 있습니다.
이때는 PGID 앞에 -
문자를 붙여 사용합니다.
kill -TERM -4287
# 다음과 같은 경우는 -4287 값이 PGID 가 아니라 신호값을 나타내는 인수로
# 인식되는 것을 방지하기 위해 -- 를 붙입니다.
# 신호값을 주지 않았으므로 기본값인 TERM 신호가 됩니다.
kill -- -4287
kill -0 PID
신호값이 0
인 kill -0
명령은 실질적으로 신호를 보내지 않지만 프로세스가 아직
살아있는지, 살아있다면 신호를 보낼수있는 권한이 되는지 테스트 하는데 사용합니다.
$ kill -0 32630; echo $? # process 가 살아있고 신호를 보낼 수 있는 권한이 됨
0
$ kill -0 32631; echo $? # process 가 존재하지 않음
bash: kill: (32631) - No such process
1
$ kill -0 1; echo $? # process 가 존재하지만 신호를 보낼 수 있는 권한이 안됨
bash: kill: (1) - Operation not permitted
1
다음은 kill 명령을 활용하여 5 초마다 dd
명령의 진행 상태를 출력합니다.
실행중인 dd 명령에 USR1 신호를 보내면 현재 진행 상태를 stderr 로 출력합니다.
# 처음 dd 명령은 데이터를 stdout 으로 출력하므로 파이프를 통해 계속 전달되고
# USR1 신호에 의한 stderr 출력은 grep 명령을 거쳐 터미널에 보여지게 됩니다.
dd bs=1M if=$lv-snapshot 2> >( grep 'copied' >&2 ) |
gzip --fast | ssh $DEST "gzip -d | dd bs=1M of=$lv" &
PID=(jobs -p) # jobs -p 는 파이프로 연결된 명령 그룹일 경우 첫번째 명령의 PID 를 출력
while kill -0 $PID; do
kill -USR1 $PID
sleep 5
done
PID 가 0 일경우
스크립트 실행 중에 특정 상황에서 자기 자신을 종료해야 될 때가 있습니다.
그런데 background 프로세스가 생성되어 실행 중이거나
스크립트 내에서 a.sh -> b.sh -> c.sh 순서로 호출하여 실행중에 있을경우 단순히 exit 명령을 사용하거나
kill -TERM $$
을 하는 것으로는 c.sh 만 종료가 되고
a.sh, b.sh 와 background 프로세스는 실행을 계속하게 됩니다.
이때 사용할 수 있는 것이 kill -TERM 0
입니다.
PID 로 0
을 사용하면 kill 명령을 호출한 프로세스와 같은 프로세스 그룹에 속한
모든 프로세스에게 신호가 전달됩니다.
따라서 c.sh 에서 kill -TERM 0
명령을 실행하면 같은 프로세스 그룹에 속한
a.sh, b.sh, c.sh 와 background 프로세스가 모두 신호를 받고 종료하게 됩니다.
# 스크립트 자신의 PGID 에 TERM 신호 보내기
kill -TERM 0 # kill -TERM -$$
kill 0 # kill -- -$$
----------------------------------
# 스크립트 자신의 PGID 에 INT 신호 보내기
kill -INT 0
$ cat a.sh $ cat b.sh $ cat c.sh
#!/bin/bash #!/bin/bash #!/bin/bash
echo start a.sh echo start b.sh echo start c.sh
./b.sh ./c.sh sleep 100 & # background 실행
kill -TERM $$ # $$ 사용
echo end a.sh echo end b.sh
echo end c.sh
# a.sh 를 실행해 보면 c.sh 만 종료가 되고 나머지는 종료되지 않는다.
$ ./a.sh
start a.sh
start b.sh
start c.sh
Terminated # c.sh 만 종료되고
end b.sh # 나머지는 종료되지 않는다.
end a.sh
$ ps ax | grep slee[p] # background 로 실행된 sleep 프로세스도 남아있다
4643 pts/14 S 0:00 sleep 100
# 이번에는 c.sh 의 'kill -TERM $$' 을 'kill -TERM 0' 로 변경한 후 실행해보면
# 같은 PGID 갖는 프로세스들이 모두 종료되는 것을 볼 수 있습니다.
$ ./a.sh
start a.sh
start b.sh
start c.sh
Terminated
$ ps ax | grep slee[p]
$