나는 내가 뭘 잘못하고 왜 그랬는지 이해하려고 정말 열심히 노력한다.
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
계속합니다. 왜?
다음 동작을 예상했습니다 (이 블로그 Signal & Bash 에 따르면 ).
launch.sh
백그라운드에서 실행중인 스크립트가있는 쉘 A 가 중단되고 Bash는 process.sh
완료 될 때까지 기다립니다 . process.sh
의 시그널 핸들러로 인해 비정상적으로 리턴 되므로 (exit 130) process.sh
, 쉘 A는 종료되어야합니다. 왜 그렇지 않습니까?
이 자식의 상태가 해당 신호로 인해 비정상적으로 종료되었음을 나타내는 경우 쉘은 정리하고 신호 처리기를 제거한 다음 다시 스스로를 죽여 OS 기본 작업 (비정상 종료)을 트리거합니다. 또는 트랩으로 설정된대로 스크립트의 신호 처리기를 실행하고 계속합니다.
첫째, 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 $$
예상되는 동작을 볼 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다