배쉬 스크립트에 SIGHUP이 보이지 않습니까?


11

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

#!/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이 스크립트에 신호를 보내려면 어떻게해야 합니까?


4
cat프로세스가 완료 되면 신호가 전달되고 신호 핸들러가 실행됩니다 . 원본 스크립트를 사용 해보고 프로세스를 끝내 Ctrl+D려면을 누르 cat십시오. cat프로세스가 포 그라운드에있는 동안 HUP신호는 작동하지 않습니다. (쉘 내장) 으로 cat교체하여 다시 시도하십시오 read.
Kusalananda

완전한. 누군가 대답으로 바꾸는 것을 좋아합니까?
Roger Lipscombe

나는 그것이 그런 식으로 작동한다는 것을 알고 있지만, 나보다 더 통찰력이있는 사람이 그 이유와 이유에 대해 대답 할 것입니다.
Kusalananda

while true; do read; done결국 사용 했습니다. 그렇지 않으면 텍스트를 입력하면 텍스트가 종료되고 Ctrl + C에서 종료되기를 원합니다.
Roger Lipscombe

답변:


21

Bash 매뉴얼 상태 :

bash가 명령이 완료되기를 기다리고 트랩이 설정된 신호를 수신하면 명령이 완료 될 때까지 트랩이 실행되지 않습니다.

즉, 신호 bash를 보낼 때 신호를 수신하더라도 SIGHUP의 트랩은 cat끝날 때만 호출됩니다 .

이 동작이 바람직하지 않은 경우 bash내장을 사용하거나 (예를 들어 read+ printf대신 루프에서 cat) 백그라운드 작업을 사용하십시오 ( Stéphane 's answer 참조 ).


9

@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"

파일 디스크립터와의 작은 춤 은 백그라운드에서 시작된 명령 bash/dev/null대해 stdin을 방향 재 지정 한다는 사실을 해결하는 것 입니다.


코드 블록이 서브 쉘에서 실행되기 때문에 이것이 작동합니까?
Pysis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.