Bash

當我 Ctrl+C 時,如何殺死並等待後台程序在 shell 腳本中完成?

  • February 7, 2016

我正在嘗試設置一個 shell 腳本,以便它執行後台程序,當我執行Ctrl``cshell 腳本時,它會殺死孩子,然後退出。

我設法想出的最好的就是這個。似乎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    

(它也會嘗試發送SIGTERMto -INT,這會導致語法錯誤,但它會先發送SIGTERM0,並且永遠不會到達那麼遠。)

因此,您的主腳本在執行andSIGTERM之前獲得了 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

引用自:https://unix.stackexchange.com/questions/55558