
쉘 스크립트에서 신호를 캡처할 때 캡처 명령은 현재 명령이 완료될 때까지 실행되지 않습니다. 예를 들어 다음 쉘 스크립트를 고려하십시오.
#!/bin/bash
trap 'echo "SIGTERM caught"' SIGTERM
i=0
while : ; do
echo "$((++i))"
timeout 10 yes >/dev/null
done
이 스크립트를 실행한 다음 SIGTERM을 프로세스에 보내려고 하면 활성 명령이 완료될 때까지 트랩 함수의 echo 문이 실행되지 않습니다.
명령을 백그라운드에 배치하고 대기를 사용하여 명령 실행 중에 신호를 처리할 수 있습니다. 예를 들어 다음과 같습니다.
#!/bin/bash
trap 'echo "SIGTERM caught"; [[ "$pid" ]] && echo "Killing $pid" && kill "$pid"' SIGTERM
i=0
while : ; do
echo "$((++i))"
timeout 10 yes >/dev/null &
pid=$!
wait
done
그러나 이제 SIGTERM이 즉시 발견되더라도 이로 인해 프로세스가 다른 신호(예: SIGINT)에 잘못 응답하게 됩니다. 예를 들어, 위 스크립트를 실행했는데 SIGTERM이 몇 분 전에 전송되면 SIGINT로 스크립트를 종료할 수 없습니다. 예를 들어, $pid
쉘 스크립트의 프로세스 ID인 경우 다음 중 하나가 프로세스를 종료합니다(후자의 경우 프로세스는 SIGTERM에 응답하기 전에 SIGINT에 의해 중단됩니다).
kill -SIGINT "$pid"
kill "$pid"; kill -SIGINT "$pid"
다음은 그렇지 않습니다(프로세스가 정지되고 SIGKILL을 전달하여 종료되어야 함).
kill "$pid"; sleep 0.01; kill -SIGINT "$pid"
SIGTERM caught
# process hangs at this point
다른 신호의 부적절한 처리를 방지하려면 트랩에 어떤 변경이 필요합니까?