echo
SIGSTOP
또는 신호가 수신될 때 응답하는 스크립트가 제공됩니다 SIGHUP
.
$cat test.sh
function clean_up {
echo "cleaning up!"
}
echo 'starting!'
trap clean_up SIGSTOP SIGHUP
sleep 100
나는 그것을 백그라운드에서 실행한다:
$./test.sh > output &
[4] 42624
그런 다음 -1
즉를 사용하여 죽였습니다.한숨을 쉬다
$kill -1 42624
하지만 trap
예상대로 작동하지 않습니다. 즉, output
파일에 내용이 없습니다 cleaning up!
.
$cat output
starting!
무슨 일이에요?
답변1
이것매뉴얼 페이지bash
상태
Bash가 명령이 완료되기를 기다리고 트랩이 설정되었다는 신호를 받으면 명령이 완료될 때까지 트랩이 실행되지 않습니다.
귀하의 예에서는 trap
완료될 때까지 실행되지 않습니다.sleep 100
답변2
실제로는 인쇄되지만 결과를 보려면 100초를 기다려야 합니다.
당신은 말한다:
$./test.sh > output &
[4] 42624
확인하면 ps aux
다음과 같은 결과가 나타납니다.
xiaobai 42624 0.0 0.1 118788 5492 pts/3 S 04:07 0:00 /bin/bash
xiaobai 42626 0.0 0.0 108192 668 pts/3 S 04:07 0:00 sleep 100
기본 스크립트 프로세스 /bin/bash, PID 42624는 여전히 절전 100이 완료되기를 기다리고 있습니다. 주 프로세스가 신호 1을 수신하더라도 sleep 100
작업을 수행할 차례가 되기 전에 완료될 때까지 기다려야 합니다 echo "cleaning up!"
. 즉, .
수면 프로세스를 백그라운드 프로세스로 만들 수 있습니다. 이 경우 스크립트 echo "cleaning up!"
프로세스가 종료되지 않은 경우에만 스크립트 프로세스가 기다리지 않고 실행될 수 있습니다.sleep process
다음 스크립트를 사용하여 개념(즉, 스크립트가 sleep
신호를 처리하기 전에 대기)을 시연할 수 있습니다.
function clean_up {
echo "cleaning up!"
}
echo 'starting!'
trap clean_up SIGHUP
sleep 5000 &
echo 1
sleep 20
echo 2
sleep 10
echo 3
평소대로 이 스크립트를 실행한 ./test.sh > output
다음 PID가 23311인지 ps aux
확인하고 실행합니다 . 또한 이 단계에 유의하세요. 즉, 스크립트가 echo 1을 입력하면 send를 보내고 이제 2가 나올 때까지 기다리면 됩니다. 그 "정리"는 이미 2에 나와 있습니다. 이전에 함께 인쇄되었습니다. 마지막으로 스크립트를 종료할 차례 입니다 ./bin/bash
kill -1 23311
cat output
sleep 20
kill -1 23311
echo 3
$ cat output
starting!
1
cleaning up!
2
3
$
위의 실험은 스크립트가 SIGHUP 신호를 수신하고 백그라운드 프로세스를 기다리지 않고 모든 이전 포그라운드 프로세스가 완료된 후 신호 처리기를 실행한다는 것을 증명합니다.
이야기가 흥미로워지는데, 원본 대본으로 이렇게 하면 어떨까 kill -1 PID_of_sleep_100
?
휴면 프로세스가 SIGHUP을 스크립트 프로세스에 반환하지 않기 때문에 인쇄하지 않고 모든 프로세스를 종료합니다.
따라서 귀하의 작업에 대한 솔루션이 있습니다. kill -1 PPID
스크립트 프로세스에 대한 SIGHUP을 승인하기 위해 (스크립트 프로세스)를 실행한 다음 kill -1 PID
(휴면 프로세스)을 실행할 수 있습니다. 이제 스크립트 프로세스는 종료하기 전에 SIGHUP 핸들러를 실행합니다. 즐거운 해킹이 되시길 바랍니다 :)
모든 신호가 동일한 것은 아닙니다.SIGKILL은 트랩을 허용하지 않습니다.. -9 스크립트 프로세스를 종료하면 휴면 프로세스는 계속 실행되고 해당 상위 PID는 1이 됩니다(검사 통과 ps -ef
).
[고쳐 쓰다]:
일반적으로 kill -N script_PID
그럴 것입니다.신호 N이 스크립트에 포착되지 않으면 간단히 스크립트를 종료하십시오.. 그러나 SIGINT에 주의하세요. kill -2 script_PID
스크립트가 이를 포착하지 못하더라도 직접 종료하지는 않습니다. 스크립트는 하위 프로세스(예: sleep 10)가 완료될 때까지 기다립니다. 이제 script_PID에서 여러 종료(예: kill -2 script_PID
AND ) 를 수행한다고 가정합니다 kill -user-defined_trap_N script_PID
.
- 자고 있으면10초 동안 기다린 후 정상적으로 돌아옵니다.또는2가 아닌 신호에 의해 사망, 스크립트는 반환 시 캐시된 신호 2를 무시한 다음 사용자 정의 _trap_N 함수를 실행합니다.
- 하지만 자면시그널 2 킬, 그러면 스크립트는 반환 시 내장 SIGINT 핸들러를 실행한 다음 user-define_trap_N을 실행하지 않고 직접 종료합니다.