그룹에서 백그라운드 프로세스를 시작하고 모두 종료합니다.

그룹에서 백그라운드 프로세스를 시작하고 모두 종료합니다.

어느 날 나는 누군가를 죽이는 대본을 쓰려고 했다.PID모든 하위 프로세스가 있지만 시간이 좀 지나면 신뢰할 수 없다고 생각됩니다. 왜냐하면 때로는 일부 하위 프로세스가 다음과 같은 결과를 낳기 때문입니다.PPID~의1.

이제 내가 찾고 있는 것은 다음 함수를 백그라운드에서 실행하고 이 함수와 curl모든 함수를 동일하게 유지하는 방법입니다.그룹, 그리고 중단되면 해당 스크립트를 종료하고 백그라운드에 남아 있는 모든 첨자를 종료합니다.

download(){
    until curl -s -S -L -A Mozilla/5.0 -m 300 "$@"; do
        echo Retrying in 5 seconds... >&2
        sleep 5
    done
}

for url in foo.com bar.com baz.com; do
    download $url >$url &
done
wait

이 함수가 필요하지 않다는 것을 알고 있지만 download이 스크립트에서 여러 번 사용하는 함수이기 때문에 여기에 포함시켰습니다. 그리고 제가 정한 최대 시간 제한은300하지만 curl일부 네트워크 오류로 인해 중단되기도 합니다.

답변1

job일반적으로 대화형 셸에서 스크립트를 호출하면 새 프로세스 그룹(일명 ) 에 배치되므로 Ctrl-C해당 스크립트를 사용하면 해당 스크립트에 의해 시작된 모든 프로세스가 SIGINT를 받게 됩니다.

백그라운드에서(여전히 대화형 셸에서) 시작하는 경우 자체 프로세스 그룹에서도 시작됩니다.

다음과 같은 방법으로 프로세스 그룹에 대해 알아볼 수 있습니다.

ps -j

( 쉘을 관리할 수 있도록 프로세스 그룹에서 명령줄을 실행하는 동작을 j나타냅니다 job control(전경/백그라운드/킬/일시중단/재개).

당신은에 대해 배울 수 있습니다일하다jobs명령을 사용하여 대화형 셸을 엽니다(모든 프로세스가 포함된 것은 아님). jobs -p프로세스 그룹 ID가 표시됩니다.

-xx프로세스 그룹 ID가 어디에 있는지 신호를 보내 프로세스 그룹의 구성원을 종료할 수 있습니다.PGID) 또는 와 함께 작업 사양을 사용합니다 %job-number. 예:

$ sleep 30 | sleep 40 &
[1] 6950 6951
$ ps -j
  PID  PGID   SID TTY          TIME CMD
 6031  6031  6031 pts/3    00:00:00 zsh
 6950  6950  6031 pts/3    00:00:00 sleep
 6951  6950  6031 pts/3    00:00:00 sleep
 6952  6952  6031 pts/3    00:00:00 ps
$ kill -- -6950
[1]  + terminated  sleep 30 | sleep 40
$ sleep 30 | sleep 40 &
[1] 6955 6957
$ jobs
[1]  + running    sleep 30 | sleep 40
$ kill %1
[1]  + terminated  sleep 30 | sleep 40

이제 대화형 셸에서 실행하지 않으면 스크립트는 상위 프로세스와 동일한 프로세스 그룹에 있게 됩니다. 따라서 해당 프로세스 그룹을 종료하면 종료하고 싶지 않은 다른 프로세스가 종료될 수 있습니다.

스크립트에서 수행할 수 있는 작업은 프로세스 그룹을 직접 시작하는 것입니다.

다음을 추가하는 것과 같습니다.

[ "$(ps -o pgid= -p "$$")" -eq "$$" ] ||
  exec perl -e 'setpgrp or die "setpgrp; $!"; exec @ARGV' -- "$0" "$@"

(우리가 프로세스 그룹 리더가 아닌 것으로 확인되면 perl스크립트 시작 부분에서 start new process group 을 호출한 후 스크립트를 다시 실행하십시오.)

이렇게 하면 스크립트가 자체 프로세스 그룹에서 실행되도록 보장할 수 있습니다.

그러나 이는 다음을 의미합니다.

something | myscript | something

대화형 쉘에서는 myscript아마도 프로세스 그룹 리더가 아닐 것입니다. 위의 작업을 수행하면 setpgrp스크립트가 더 이상 터미널의 포그라운드 프로세스 그룹에 있지 않으므로 Ctrl-C종료되지 않습니다.

관련 정보