나는 프로세스 그룹을 배우고 있는데, 이는 나에게 새로운 것입니다. (저는 무엇보다도 다음 답변을 따르려고 노력했습니다.SIGINT가 상위 프로세스로 전송될 때 하위 프로세스로 전파되지 않는 이유는 무엇입니까?). 시도했지만 프로세스 그룹의 ID가 사라지는 것 같아서 삭제할 수 없습니다.
$ sleep 1000 &
[1] 6468
$ ps ax -O tpgid | grep sleep
6468 6511 S pts/4 00:00:00 sleep 1000
6512 6511 S pts/4 00:00:00 grep --color=auto sleep
$ kill -9 -6511
bash: kill: (-6511) - No such process
$ ps ax -O tpgid | grep sleep
6468 6515 S pts/4 00:00:00 sleep 1000
6516 6515 S pts/4 00:00:00 grep --color=auto sleep
$ ps ax -O tpgid | grep sleep
6468 6517 S pts/4 00:00:00 sleep 1000
6518 6517 S pts/4 00:00:00 grep --color=auto sleep
왜 이런 일이 발생하며, 어떻게 잡아서 죽일 수 있습니까? 나는 무엇을 얻었고, 무엇을 잘못했는가?
GNU bash, 버전 4.3.42(1)-릴리스(x86_64-pc-linux-gnu)
답변1
이는 프로세스 그룹 ID(PGID)를 인쇄하는 대신 "Control tty Process Group ID" tpgid를 인쇄하기 때문입니다. 설명된 대로 man ps
:
tpgid TPGID ID of the foreground process group on the tty
(terminal) that the process is connected to, or
-1 if the process is not connected to a tty.
따라서 표시되는 것은 포그라운드 프로세스의 PID입니다. 귀하의 경우에는 프로그램입니다 ps
.
$ sleep 1000 &
[1] 6745
$ ps ax -O tpgid | grep -E 'sleep|ps a'
6745 7136 S pts/1 00:00:00 sleep 1000
7136 7136 R pts/1 00:00:00 ps ax -O tpgid
7137 7136 S pts/1 00:00:00 grep --color -E sleep|ps a
위에 표시된 것처럼 인쇄된 tpgid 값은 프로세스의 PID입니다 ps
. 당신이 찾고 있는 것은 pgid
다음이 아닙니다 tpgid
:
pgid PGID process group ID or, equivalently, the process ID
of the process group leader. (alias pgrp).
$ ps ax -O pgid | grep -E 'sleep|ps a'
8414 8414 S pts/1 00:00:00 sleep 1000
8656 8656 R pts/1 00:00:00 ps ax -O pgid
8657 8656 S pts/1 00:00:00 grep --color -E sleep|ps a
물론 실제로 어떤 프로세스 그룹도 실행하고 있지 않기 때문에(예를 들어 한 스크립트가 다른 스크립트를 호출할 때 발생) PGID는 sleep
해당 PID와 동일합니다. 그러나 원하는 경우 실제로 다음과 같이 죽일 수 있습니다.
$ kill -9 -8414
$ ps ax -O pgid | grep -E 'sleep|ps a'
10065 10065 R pts/1 00:00:00 ps ax -O pgid
10066 10065 S pts/1 00:00:00 grep --color -E sleep|ps a
[1]+ Killed sleep 1000
보다 유익한 예는 다음과 같은 스크립트를 실행하는 것입니다.
#!/bin/bash
sleep 1000 &
sleep 1000 &
sleep 1000 &
sleep 1000
이것을 다른 이름으로 저장 foo.sh
하고 실행하면 다양한 sleep
명령이 모두 동일한 PGID를 갖게 됩니다.
$ foo.sh &
[1] 13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
13555 13555 S pts/1 00:00:00 /bin/bash /home/terdon/scripts/foo.sh
13556 13555 S pts/1 00:00:00 sleep 1000
13557 13555 S pts/1 00:00:00 sleep 1000
13558 13555 S pts/1 00:00:00 sleep 1000
13559 13555 S pts/1 00:00:00 sleep 1000
따라서 각 하위 프로세스는 상위 프로세스의 프로세스 그룹에 속합니다 foo.sh
. 지금 프로세스 그룹을 종료하면 모든 프로세스가 종료됩니다.
$ kill -9 -13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
[1]+ Killed foo.sh