Bash
當 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_script``SIGINT``SIGTERM
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
’s 手冊頁,因此我可能錯過了解決方案。我想這就是像 Chromium 這樣的“真實”程序在你發送它們時所做的事情
SIGTERM
來自https://major.io/2010/03/18/sigterm-vs-sigkill/
一旦收到 SIGTERM,應用程序就可以確定它想要做什麼。雖然大多數應用程序會清理它們的資源並停止,但有些可能不會。
trap
對呼叫程序信號本身做出反應。但是你必須在收到信號之前呼叫它。我的意思是,在腳本的開頭。此外,如果您想使用
kill -- -$$
,它也將信號發送到您的腳本,您需要在執行 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