Bash
當我 Ctrl+C 時,如何殺死並等待後台程序在 shell 腳本中完成?
我正在嘗試設置一個 shell 腳本,以便它執行後台程序,當我執行
Ctrl``c
shell 腳本時,它會殺死孩子,然後退出。我設法想出的最好的就是這個。似乎
kill 0 -INT
在等待發生之前也殺死了腳本,所以shell腳本在孩子完成之前就死了。關於如何讓這個 shell 腳本在發送後等待孩子死去的任何想法
INT
?#!/bin/bash trap 'killall' INT killall() { echo "**** Shutting down... ****" kill 0 -INT wait # Why doesn't this wait?? echo DONE } process1 & process2 & process3 & cat # wait forever
你的
kill
命令是倒退的。與許多 UNIX 命令一樣,以減號開頭的選項必須先出現,然後再出現其他參數。
如果你寫
kill -INT 0
它將
-INT
視為一個選項,並發SIGINT
送到0
(0
是一個特殊數字,表示目前程序組中的所有程序)。但是如果你寫
kill 0 -INT
它看到
0
,決定沒有更多選項,因此SIGTERM
預設使用。並將其發送到目前程序組,就像你做的一樣kill -TERM 0 -INT
(它也會嘗試發送
SIGTERM
to-INT
,這會導致語法錯誤,但它會先發送SIGTERM
到0
,並且永遠不會到達那麼遠。)因此,您的主腳本在執行and
SIGTERM
之前獲得了 a 。wait``echo DONE
添加
trap 'echo got SIGTERM' TERM
在頂部,就在之後
trap 'killall' INT
並再次執行它來證明這一點。
正如 Stephane Chazelas 指出的那樣,預設情況下,您的背景孩子(
process1
等)將SIGINT
被忽略。無論如何,我認為發送
SIGTERM
會更有意義。最後,我不確定是否
kill -process group
能保證先去找孩子。關閉時忽略信號可能是個好主意。所以試試這個:
#!/bin/bash trap 'killall' INT killall() { trap '' INT TERM # ignore INT and TERM while shutting down echo "**** Shutting down... ****" # added double quotes kill -TERM 0 # fixed order, send TERM not INT wait echo DONE } ./process1 & ./process2 & ./process3 & cat # wait forever