다음과 같은 스크립트가 있다고 가정해 보겠습니다.
#!/usr/bin/env zsh
./subscript.sh &
# do stuff
...
# do more stuff
subscript.sh
다음과 같은 경우 실행 중인 프로세스(및 이에 의해 시작된 모든 프로세스)가 완전히 종료되기를 원합니다 .
- 위의 스크립트가 종료됩니다.
- 위의 스크립트는 어떤 이유로든 종료됩니다.
위 사항을 어떻게 시행할 수 있나요? 이것은 쉘에 의해 자동으로 처리됩니까?
답변1
쉘은 하위 프로세스를 자발적으로 종료하지 않을 것입니다. 결국 백그라운드 작업은 백그라운드에서 실행되어야 하며 상위 프로세스의 수명에는 관심이 없습니다. (대화형 쉘은 어떤 상황에서는 종료 시 하위 프로세스를 종료합니다. 이는 항상 바람직하지는 않습니다.nohup
.)
쉘 스크립트가 종료되거나 포착 가능한 신호에 의해 종료될 때 백그라운드 작업을 종료하도록 할 수 있습니다. 작업의 프로세스 ID를 기록하고 트랩에서 종료합니다. 이는 하위 프로세스가 아닌 작업(백그라운드에서 시작된 원래 프로세스)만 종료한다는 점에 유의하세요.
jobs=()
trap '((#jobs == 0)) || kill $jobs' EXIT HUP TERM INT
…
subscript1 & jobs+=($!)
subscript2 & jobs+=($!)
…
모든 프로세스와 해당 하위 프로세스를 확실히 종료하려면 추가 계획이 필요합니다. 한 가지 방법은 모든 프로세스가 고유한 파일을 열도록 배열하는 것입니다. 모두 종료하려면 이 파일이 열려 있는 모든 프로세스를 종료하세요. 하위 프로세스는 파일을 닫아 탈출할 수 있습니다.
#!/bin/sh
lock_file=$(mktemp)
exec 3<"$lock_file"
your_script
status=$?
exec 3<&-
fuser -k "$lock_file"
exit $status
답변2
EXIT를 트랩하고 스크립트의 프로세스 그룹에 신호를 보낼 수 있습니다.
리눅스에서
trap 'kill -SIGTERM 0' EXIT
FreeBSD에서
trap 'kill -15 -$$' EXIT
SIGKILL
스크립트가 무조건 종료되므로 이것이 작동하지 않는 유일한 신호입니다.