bash
Kubuntu Trusty 64비트에서 4.3을 실행합니다. 다음 두 문서를 참조하세요.
Trapatint.sh
#! /bin/bash
trap "echo Exiting" INT
cat </dev/urandom >/dev/null
echo Hello
Captureexit.sh
#! /bin/bash
trap "echo Exiting" EXIT
cat </dev/urandom >/dev/null
echo Hello
이제 ^C를 누르면 SIGINT를 잡으면 둘 다 인쇄되고 EXIT를 잡으면 인쇄 Exiting
되지만 추가 줄 바꿈이 포함됩니다.Hello
Exiting
$ ./trapping-int
^CExiting
Hello
$ ./trapping-exit
^CExiting
$
다른 동작의 이유를 알고 싶습니다. 또한 ^C에 INT가 제공되어도 EXIT가 항상 호출된다고 안전하게 가정할 수 있습니까?
두 스크립트 모두에서 마지막 줄을 주석 처리하면 SIGINT를 포착하면 더 이상 Hello가 인쇄되지 않지만 EXIT를 포착하면 여전히 추가 줄바꿈이 인쇄됩니다. 여기에 대한 이유도 알고 싶습니다.
감사해요!
답변1
먼저, 신호 및 셸에 대한 몇 가지 사실을 요약합니다.
키보드에서 CTRL+C를 누르면 포그라운드 프로세스의 프로세스 그룹에 있는 모든 프로세스에 SIGINT가 전송됩니다. 이 경우 스크립트를 해석하는
cat
명령과bash
프로세스 모두 SIGINT를 수신한다는 의미입니다.을 트랩할 때 처리기에서 명시적으로 종료하지 않는 한 더 이상 프로세스가 종료되지 않습니다
INT
.INT
를 트랩할 때
EXIT
인수는 특정 신호에서 실행되지 않고 쉘이 종료될 때 실행됩니다.
trapping-int.sh
이러한 사실을 고려하면 다음과 같은 일이 발생한다는 것을 알고 있으므로 의 동작은 간단합니다.
- 프로세스는
cat
SIGINT를 수신하고 실행을 종료합니다. - 프로세스
bash
는 SIGINT를 수신하고 신호 처리기를 실행하여 "Exiting\n"을 에 인쇄합니다STDOUT
. - 프로세스
bash
는 실행을 계속하고 "Hello\n"을 에 인쇄합니다STDOUT
. bash
스크립트 끝에 도달하면 프로세스가 종료됩니다 .
동작 trapping-exit.sh
도 대부분 간단합니다.
- 프로세스는
cat
SIGINT를 수신하고 실행을 종료합니다. - 프로세스
bash
는 SIGINT를 수신하고 신호 처리기가 없으므로 종료됩니다.echo
신호를 받은 후 즉시 종료되기 때문에 명령을 실행 /실행하지 않습니다 . bash
프로세스가 종료 중이므로 핸들러EXIT
가 실행되고 "Exiting\n"이 에 인쇄됩니다STDOUT
.
남은 질문은 "개행 문자는 어디에서 오는가?"입니다. 저는 배쉬 자체가 SIGINT
개행 문자를 인쇄하는 핸들러를 설치하고 있다고 생각합니다.
스크립트 에서 trapping-int.sh
Bash의 핸들러를 재정의하여 SIGINT
추가 줄 바꿈을 얻지 않습니다.