하위 프로세스가 비정상적으로 종료되도록 하는 신호로 인해 bash가 종료되지 않습니다.

하위 프로세스가 비정상적으로 종료되도록 하는 신호로 인해 bash가 종료되지 않습니다.

나는 내가 뭘 잘못하고 있는지, 그리고 그 이유가 무엇인지 이해하려고 정말 열심히 노력하고 있습니다.

launch.sh시작 스크립트 가 있습니다 process.sh.

start.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의 신호 처리기가 예외 return(exit 130)을 발생시키기 때문에 process.sh쉘 A는 종료되어야 합니다 . 왜 안 돼?

하위 프로세스의 상태가 이 신호로 인해 비정상적으로 종료되었음을 나타내면 쉘은 정리하고 해당 신호 처리기를 제거한 다음 다시 자체 종료하여 운영 체제 기본 동작(비정상 종료)을 트리거합니다. 또는 트랩 설정에 따라 스크립트의 신호 처리기를 실행한 다음 계속합니다.

답변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로 인해 프로세스가 종료되면 bash는 SIGINT로 인해 종료를 감지하여 프로세스 외부에서 이를 130으로 설정하므로 종료 상태는 130입니다.bash가 $를 설정하는 이유는 무엇입니까? (종료 상태)가 Ctrl-C 또는 Ctrl-Z에서 0이 아닙니까?

둘째, SIGINT를 처리한 다음 종료되는 프로세스는 SIGINT를 사용하여 스스로 종료되어야 합니다. Greg의 wiki(쉘에 대한 훌륭한 자료)에는이에 대한 참고 사항:

EXIT 트랩을 사용하는 대신 SIGINT에 대한 핸들러를 설정하기로 선택한 경우 SIGINT에 대한 응답으로 종료되는 프로세스가SIGINT로 자살하세요발신자에게 문제를 일으키지 않기 위해 단순히 종료하는 것이 아닙니다. 그러므로:

trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT

이제 다음과 같이 변경하면 exit 130:

trap - INT
kill -INT $$

예상되는 동작을 볼 수 있습니다.

관련 정보