当 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

相关内容