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

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

일전에 나는 누군가를 죽이는 스크립트를 작성하려고 했습니다.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가 표시됩니다.

-x프로세스 그룹 ID가 어디에 있는지 신호를 보내 프로세스 그룹의 구성원을 종료할 수 있습니다 x(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( 프로세스 그룹 리더가 아닌 것으로 감지되면 새 프로세스 그룹을 시작하도록 호출한 후 스크립트를 다시 실행합니다 .)

이렇게 하면 스크립트가 자체 프로세스 그룹에서 실행된다는 것이 보장됩니다.

하지만 이것이 의미하는 바는 다음과 같습니다.

something | myscript | something

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

관련 정보