EXIT 잡기가 INT와 다르게 동작하는 이유

EXIT 잡기가 INT와 다르게 동작하는 이유

bashKubuntu 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되지만 추가 줄 바꿈이 포함됩니다.HelloExiting

$ ./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이러한 사실을 고려하면 다음과 같은 일이 발생한다는 것을 알고 있으므로 의 동작은 간단합니다.

  • 프로세스는 catSIGINT를 수신하고 실행을 종료합니다.
  • 프로세스 bash는 SIGINT를 수신하고 신호 처리기를 실행하여 "Exiting\n"을 에 인쇄합니다 STDOUT.
  • 프로세스 bash는 실행을 계속하고 "Hello\n"을 에 인쇄합니다 STDOUT.
  • bash스크립트 끝에 도달하면 프로세스가 종료됩니다 .

동작 trapping-exit.sh도 대부분 간단합니다.

  • 프로세스는 catSIGINT를 수신하고 실행을 종료합니다.
  • 프로세스 bash는 SIGINT를 수신하고 신호 처리기가 없으므로 종료됩니다. echo신호를 받은 후 즉시 종료되기 때문에 명령을 실행 /실행하지 않습니다 .
  • bash프로세스가 종료 중이므로 핸들러 EXIT가 실행되고 "Exiting\n"이 에 인쇄됩니다 STDOUT.

남은 질문은 "개행 문자는 어디에서 오는가?"입니다. 저는 배쉬 자체가 SIGINT개행 문자를 인쇄하는 핸들러를 설치하고 있다고 생각합니다.

스크립트 에서 trapping-int.shBash의 핸들러를 재정의하여 SIGINT추가 줄 바꿈을 얻지 않습니다.

관련 정보