이 짧은 스크립트를 고려해보세요. 두 개의 신호 처리기를 설정합니다. 하나는 for USR1
이고 다른 하나는 입니다 USR2
. 그런 다음 대화형 셸 세션을 시작합니다.
#!/bin/sh
sigusr1_handler () {
variable=1
printf "SIGUSR1: variable is now %d\n" "$variable"
}
sigusr2_handler () {
variable=2
printf "SIGUSR2: variable is now %d\n" "$variable"
}
variable=0
printf "At beginning, variable is %d\n" "$variable"
trap 'sigusr1_handler' USR1
trap 'sigusr2_handler' USR2
/bin/sh
printf "At end, variable is %d\n" "$variable"
실행하세요:
$ ./script.sh
At beginning, variable is 0
$ kill -s USR1 $PPID
$ kill -s USR2 $PPID
$ kill -s USR1 $PPID
$ exit
SIGUSR1: variable is now 1
SIGUSR2: variable is now 2
At end, variable is 2
내가 가장 먼저 알아차린 것은 상위 쉘이 하위 쉘이 종료될 때까지 신호를 처리하지 않는다는 것입니다. POSIX에서 문서화한 내용이라는 것을 알게 되었기 때문에 문서를 제대로 읽지 못한 책임은 본인에게 있습니다.
두 번째로 알아차린 점은 신호가 대기열에 추가되지 않았다는 것입니다. 이것은 아마도 매우 기본적인 지식이지만 간과했습니다. 하위 프로세스가 실행되는 동안 생성된 신호는 보류 상태에 있고 보류 신호가 생성되면 가정합니다.다시, 단순히 무시됩니다.
내 문제는 나야필요대화형 셸(하위 프로세스)이 실행되는 동안 신호를 상위 프로세스의 신호 처리기에 전달합니다. 자식 프로세스가 종료된 후의 값을 기준으로 결정을 내리고 싶고 $variable
위의 Interactive 세션과 동일한 순서로 신호가 생성되면$variable
~ 해야 하다스크립트 끝의 값은 1입니다.
그래서 내 간단한 해결책은 하위 프로세스를 비동기 백그라운드 작업으로 시작하는 것이었습니다.
/bin/sh &
wait
(시그널 전달시 반환 값을 확인해야 한다는 것을 알고 있지만 wait
나중에 설정하겠습니다.)
이것은 작동하지 않습니다. 하위 프로세스가 즉시 종료됩니다.
$ sh -x script.sh
+ variable=0
+ printf At beginning, variable is %d\n 0
At beginning, variable is 0
+ trap sigusr1_handler USR1
+ trap sigusr2_handler USR2
+ wait
+ /bin/sh
+ printf At end, variable is %d\n 0
At end, variable is 0
wait
(위의 추적 출력에서는 쉘 이전에 실행된 것처럼 보이지만 스크립트에서는 올바른 순서로 실행하고 있습니다.)
사용법에는 /bin/sh -i &
변화가 없습니다 . 나는 추가 시도를 하고 그것과 이들의 조합( )으로 /bin/sh -s
리디렉션했지만 소용이 없었습니다./dev/stdin
-i -s
이제 내 질문은: 스크립트에서 비동기식으로 대화형 셸을 시작하는 방법입니다.전망상위 프로세스가 신호가 생성되자마자 신호를 전달할 수 있도록 프로세스(즉, 입력을 허용하는 대화형 셸)를 처리합니까? 아니면 다른 디자인이 있을 수도 있나요?
답변1
Katsura Sato의 의견은 내 질문에 대한 완전한 답변입니다.
신호가 대기열에 있는지 여부는 시스템에 따라 다릅니다.. 신호가 특정 순서로 전달된다는 보장은 없습니다. 동일한 유형의 신호는 생성된 순서대로 전달될 수 있지만 이는 시스템에 따라 다릅니다(Linux에서도 마찬가지). 여러 명령을 보내야 하는 경우 파이프를 명령 채널로 사용하세요.