當 SIGINT 或 SIGTERM 發送到父腳本本身而不是子進程時執行命令或函數

當 SIGINT 或 SIGTERM 發送到父腳本本身而不是子進程時執行命令或函數

假設我有這個script.sh

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

echo "Some other text"
#other commands here
sleep infinity

我想在收到或時script.sh執行該函數 例如:exit_scriptSIGINTSIGTERM

killall script.sh # it will send SIGTERM to my script

我希望我的腳本執行這個

exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

我嘗試使用來實現此功能trap

trap exit_script SIGINT SIGTERM

回答我問題的人證明我錯了。
但它不起作用,因為trap似乎只對發送到子/子進程的信號做出反應。作為初學者,我無法破解trap的手冊頁,所以我可能錯過了解決方案。

我想這就是像 Chromium 這樣的“真正”程序在發送時所做的事情SIGTERM

https://major.io/2010/03/18/sigterm-vs-sigkill/

一旦收到 SIGTERM,應用程式就可以確定它想要做什麼。雖然大多數應用程式會清理資源並停止,但有些應用程式可能不會。

答案1

trap對呼叫進程訊號本身做出反應。但你必須在收到訊號之前呼叫它。我的意思是,在你的腳本的開頭。

此外,如果你想使用kill -- -$$,它也將訊號發送到你的腳本,你需要在運行kill之前清除陷阱,否則你將以無限結束殺戮&&陷阱環形。

例如:

#!/bin/bash
exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    trap - SIGINT SIGTERM # clear the trap
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

trap exit_script SIGINT SIGTERM

echo "Some other text"
#other commands here
sleep infinity

正如評論中所解釋的,問題在於腳本接收到訊號,但正在等待睡眠程序結束,然後再處理接收到的訊號。因此,您應該殺死子進程(在本例中為睡眠進程)才能執行陷阱操作。您可以使用以下方法來做到這一點:

kill -- -$(pgrep script.sh)

或如評論所述:

killall -g script.sh

相關內容