Bash 스크립트에 SIGHUP이 표시되지 않습니까?

Bash 스크립트에 SIGHUP이 표시되지 않습니까?

다음 스크립트가 있습니다.

#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat    # wait indefinitely

SIGHUP(사용 ) 을 보내면 kill -HUP pid아무 일도 일어나지 않습니다.

스크립트를 약간 변경하면 다음과 같습니다.

#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT    # add this
trap "echo HUP" SIGHUP
cat    # wait indefinitely

...그러면 echo HUP종료 시 스크립트가 올바르게 작동합니다(Ctrl+C를 누를 때).

roger@roger-pc:~ $ ./hupper.sh 
We are 6233
^CHUP

어떻게 되어가나요? SIGHUP이 스크립트에 신호를 어떻게 보내야 합니까 (반드시 그런 것은 아님)?

답변1

배쉬 매뉴얼상태:

Bash가 명령이 완료되기를 기다리고 트랩이 설정되었다는 신호를 받으면 명령이 완료될 때까지 트랩이 실행되지 않습니다.

즉, 신호가 bash전송될 때 신호가 수신되었더라도 SIGHUP의 트랩은 cat신호가 끝날 때만 호출됩니다.

이 동작이 바람직하지 않은 경우 bash내장 함수(예: 루프에서 + read)를 사용하거나 백그라운드 작업을 사용할 수 있습니다(참조printfcat스티븐의 대답).

답변2

@xhienne가 이유를 설명했습니다.하지만 신호가 즉시 작동하도록 하려면(스크립트를 종료하는 대신) 코드를 다음과 같이 변경할 수 있습니다.

#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP

{ cat <&3 3<&- & pid=$!; } 3<&0

while
  wait "$pid"
  ret=$?
  "$interrupted"
do
  interrupted=false
done
exit "$ret"

파일 설명자를 사용하는 작은 방법은 stdin이 백그라운드에서 시작된 명령 bash으로 리디렉션된다는 사실을 피하는 것입니다 ./dev/null

답변3

EXIT에 트랩이 있을 때 스크립트는 신호를 수신할 때 외부 명령이 끝날 때까지 기다리지 않는다는 것을 알았습니다. 예시 스크립트:

$ cat test-trap 
#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat

실행하세요:

$ ./test-trap
We are 24814

보내기:

$ ./test-trap
We are 24814
# Doing `kill -HUP 24814` in another terminal
Trapping EXIT
Hangup

하지만 혼란스러운 버려진 고양이가 있을 수도 있습니다.

cat: -: Input/output error

이 문제를 해결하려면 트랩이 호출한 함수에서 하위 프로세스를 검색하고 종료해야 할 수도 있습니다.

Ctrl+를 누르세요 C:

$ ./test-trap
We are 24814
^CTrapping EXIT

Ctrl이제 + D대신 Ctrl+ 를 누르면 Ccat 명령이 정상적으로 종료됩니다 . 그러나 스크립트가 끝나면 트랩이 실행됩니다.

$ ./test-trap
We are 40183
# I pressed Ctrl+D here...
Trapping EXIT

스크립트 끝에서 트랩을 취소하여 이를 방지할 수 있습니다.

#!/bin/bash
echo "We are $$"
trap "echo 'Trapping EXIT'" EXIT
cat
trap - EXIT

EXIT를 잡는 다양한 동작에 대한 문서를 찾을 수 없습니다. 어쩌면 다른 사람도 그럴 수 있지 않을까?

관련 정보