쉘이 강제 종료되면 두 명령도 모두 종료되도록 Bash에서 두 명령을 병렬로 실행할 수 있는 방법이 있습니까?
간단한 방법은 &
작동하지 않습니다.
sh -c 'sleep 6 & sleep 3'
그러면 죽더라도 첫 번째 사람은 sleep
계속해서 돌아다닐 것입니다.sh
답변1
Trap을 사용하는 @lesmana의 솔루션은 전통적인 접근 방식이지만 언급한 대로 이 kill -9
상황을 처리할 수 없습니다.
메인 프로세스를 모니터링하고 메인 프로세스가 종료될 때 kill 명령을 실행하도록 프로세스를 설정하는 대안이 있습니다. 모니터링을 수행하는 간단한 방법은 모니터에 대한 파이프를 설정하는 것입니다. 그리고 주 프로세스가 종료되면 커널은 모니터가 감지할 수 있는 파이프를 닫습니다.
이것은 예이다
#!/bin/bash
# show monitoring main process - Icarus Sparry
# [email protected]
# Handler function. Reads from stdin. If it doesn't read the word clean
# then send SIGINT to the process group.
handler(){
read
[ "$REPLY" = "clean" ] || kill -INT -$$
}
# invoke handler as a coprocess.
coproc handler
# some work in the background, wait for 20 seconds and print a message
{ sleep 20 ; echo bye 20 ; } &
# some work in the foreground
sleep 5 ; echo bye 5
# At this point tell the coprocess it was a clean end, so don't
# terminate the background
echo clean >&"${COPROC[1]}"
bye 5
이 명령을 실행하면 5초 후와 15초 후에 출력됩니다 bye 20
. 프로세스를 종료하면 보조 프로세스가 백그라운드 절전 모드를 종료하게 됩니다.
포그라운드 작업이 완료되었을 때 백그라운드 처리를 종료하려면 Final을 생략하고 echo clean >&"${COPROC[1]}"
선택적으로 핸들러에서 제거하고 [ "$REPLY" = "clean" ] ||
읽기 및 종료는 그대로 둡니다.
답변2
trap 'kill 0' EXIT
메인 스크립트에서 사용됩니다. 스크립트가 종료되면 모든 자식이 종료됩니다. 스크립트가 어떻게 종료되는지는 중요하지 않습니다. 와는 별개로 kill -9
. 이에 대해서는 나중에 자세히 설명하겠습니다.
시연하기 위해 두 개의 파일을 만들었습니다.
$ cat killchildren
#! /bin/sh
trap 'echo killing all children; kill 0' EXIT # this is the important line
./sleepx 4 &
./sleepx 2
echo killchildren done
$ cat sleepx
#! /bin/sh
trap 'echo sleep$1 killed' EXIT # just print that it was killed
sleep $1
trap - EXIT # clear trap so not print that it was killed
echo sleep$1 done
여기서는 실행되고 동일하게 유지됩니다.
$ ./killchildren
sleep2 done
killchildren done
killing all children
sleep4 killed
여기서는 정상적으로 종료됩니다. kill
(빠른 타이핑을 하지 않기 때문에 수면 시간을 늘렸습니다.)
$ ./killchildren &
[1] 13248
$ kill 13248
killing all children
sleep8 killed
sleep10 killed
[1]+ Terminated ./killchildren
여기서는 죽었어kill -9
$ ./killchildren &
[1] 13259
$ kill -9 13259
[1]+ Killed ./killchildren
$ # ... time passes ...
sleep8 done
sleep10 done
기본 스크립트에는 종료 메시지가 없으며 하위 스크립트는 종료되지 않습니다.
많이 테스트되지 않았습니다. 2018년 현재 이것은 적어도 아치 리눅스에서는 sh와 함께 작동합니다.
기본 스크립트가 작동하지 않으면 작동하지 않습니다 kill -9
. 의미론은 kill -9
프로세스가 어떤 작업도 수행하지 않고 즉시 종료되어야 하기 때문입니다. 트랩 처리도 하지 않습니다.
즉, 프로세스를 죽이는 것은 무엇이든 사용해서는 안 됩니다 kill -9
. 이것은 버그라고 생각합니다. 그 이유에 대한 자세한 내용은 다음과 같습니다 kill -9
.