
나는 내가 무엇을 잘못하고 있고 그 이유가 무엇인지 이해하려고 정말 열심히 노력합니다.
launch.sh
를 시작하는 스크립트 가 있습니다 process.sh
.
launch.sh
#!/bin/bash
while true; do
./process.sh
done
process.sh
#!/bin/bash
function signalHandler() {
for i in {1..2}; do
sleep 0.1s
echo "process.sh: cleanup $i"
done
exit 130
}
trap "signalHandler" "SIGINT"
while true; do
sleep 1s
done
내가 달릴 때
./launch.sh &
그런 다음 그것을 죽여라.
kill -s SIGINT -$!
여기서 $!
마지막 명령(launch.sh)의 PID를 가져오고 마이너스는 모든 하위 항목에 신호를 보낸 다음 launch.sh
계속됩니다. 왜?
나는 다음과 같은 동작을 예상했습니다(이 블로그에 따르면)신호 및 배쉬) :
백그라운드에서 실행 중인 스크립트가 있는 셸 A가 launch.sh
중단되고 Bash는 process.sh
완료될 때까지 기다립니다. process.sh
의 시그널 핸들러로 인해 비정상적으로(130번 종료) 반환되므로 쉘 process.sh
A를 종료해야 합니다. 왜 그렇지 않습니까?
이 하위 항목의 상태가 해당 신호로 인해 비정상적으로 종료되었음을 나타내는 경우 셸은 정리하고 해당 신호 처리기를 제거한 다음 다시 자체 종료하여 OS 기본 작업(비정상 종료)을 트리거합니다. 또는 트랩으로 설정된 대로 스크립트의 신호 처리기를 실행하고 계속합니다.
답변1
첫째, exit 130
비정상적인 종료가 아닙니다. 이는 종료 상태가 130인 일반적인 종료입니다. 에서 볼 수 있듯이man 3 wait
(POSIX):
If the information pointed to by stat_loc was stored by a call to
waitpid() that specified the WUNTRACED and WCONTINUED flags,
exactly one of the macros WIFEXITED(*stat_loc), WIFSIGNALED(*stat_loc),
WIFSTOPPED(*stat_loc), and WIFCONTINUED(*stat_loc) shall evaluate to
a non-zero value.
WIFEXITED
정상적인 종료를 확인하고, WIFSIGNALLED
잡히지 않은 신호로 인해 종료됩니다. 이들은 상호 배타적이므로 an exit 130
이 정상입니다.
프로세스가 SIGINT에 의해 종료될 때 종료 상태가 130인 것은 bash가 SIGINT로 인한 종료를 감지했기 때문에 프로세스 외부에서 종료 상태를 130으로 설정했기 때문입니다.bash가 $를 설정하는 이유는 무엇입니까? (종료 상태)를 Ctrl-C 또는 Ctrl-Z에서 0이 아닌 값으로 설정하시겠습니까?
둘째, SIGINT를 처리한 다음 종료되는 프로세스는 SIGINT를 사용하여 스스로 종료되어야 합니다. Greg의 위키(쉘 관련 훌륭한 리소스)에는 다음이 있습니다.이것에 대한 메모:
EXIT 트랩을 사용하는 대신 SIGINT에 대한 핸들러를 설정하기로 선택한 경우 SIGINT에 대한 응답으로 종료되는 프로세스가SIGINT로 자살단순히 종료하는 대신 호출자에게 문제를 일으키지 않도록 합니다. 따라서:
trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT
이제 다음과 같이 변경했다면 exit 130
:
trap - INT
kill -INT $$
예상되는 동작을 볼 수 있습니다.