일부 보조 스크립트를 제어하는 기본 스크립트가 있습니다. 터미널에서 인터럽트 신호를 보내면 부모는 trap
신호를 잡았지만 자식은 잡지 못하고 그 이유를 이해할 수 없습니다. 기본 터미널 설정을 변경하지 않았습니다( stty
어디에서도 실행하지 않습니다).
내 상위 및 하위 스크립트와 터미널 출력은 다음과 같습니다.
부모:
#!/bin/sh
./child.sh &
for sig in $(kill -l) ; do
trap "echo parent:$sig" $sig
done
wait
어린이:
#!/bin/sh
cat < /dev/tty &
PID=$!
for sig in $(kill -l) ; do
trap "echo child:$sig" $sig
done
wait
터미널 상호작용:
[prompt]$ ./parent.sh
^Cparent:INT
cat: stdin: Input/output error
[prompt]$
고쳐 쓰다
macOS 및 CentOS에서 스크립트를 테스트했는데 위 동작이 발생했습니다. 기본 Bourne 호환 쉘을 사용하여 FreeBSD에서 이것을 테스트할 때 하위 프로세스가 수신하는 신호는 CHLD
.
답변1
비대화형 셸에서 비동기적으로 실행되는 명령의 경우(실제로 작업 제어가 활성화되지 않은 경우) POSIX 규정 준수에서 SIGINT 및 SIGQUIT가 무시됩니다.sh
POSIX 요구 사항일부 쉘은 이를 무시하지만.
또 다른 POSIX 요구 사항문제는 쉘이 시작될 때 신호가 무시되면 무시할 수 없으므로 망한다는 것입니다.
여기에서는 성가신 "기능"(적어도 현재 버전에서는)이 없는 기능을 대신 사용할 수 있습니다 zsh
.sh
그럼에도 불구하고, 쉘에서의 신호 처리는 신뢰성이 가장 낮고 이식성이 떨어지는 측면 중 하나입니다. 동작은 셸마다 그리고 동일한 셸의 서로 다른 버전 간에도 크게 다르다는 것을 알 수 있습니다. 평범하지 않은 것을 시도하려는 경우 심각한 잡아당김과 머리 긁힘을 겪을 준비를 하십시오.
어떤 일이 발생하는지 더 잘 제어할 수 있도록 다른 언어를 사용하는 것이 좋습니다.
또한 나는 가능한 모든 신호를 맹목적으로 처리하지 않고 수신할 것으로 예상하고 처리 방법을 알고 있는 신호만 처리합니다. 예를 들어, SIGCHLD(프로세스를 생성하고 종료를 처리하는 작업이므로 쉘 자체에 관심이 있음)를 포착하면 원하는 대로 작동하지 않을 수 있습니다.