将SIGINT或SIGTERM发送给父脚本本身而不是子进程时执行命令或函数


11

假设我有这个 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时,它接收SIGINTSIGTERM 例如:

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后,应用程序可以确定其要执行的操作。虽然大多数应用程序将清理其资源并停止运行,但有些可能不会。


2
一般而言,发誓被认为是不适当的礼貌性言语

编辑建议已批准好的,做好了,
不好意思

并不是说没有乐趣,而是被认为令人反感
2016年

1
@cat我已经考虑过您的论点,您说得对,对不起,我的
傻话

Answers:


15

trap对调用过程信号本身做出反应。但是您必须在收到信号之前先调用它。我的意思是,在脚本的开头。

此外,如果要使用kill -- -$$,它还将信号也发送到脚本,则需要在运行kill之前清除陷阱,否则将以无限的kill && trap循环结束。

例如:

#!/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

1
我可能会丢失一些东西,因为它不起作用,这是我的工作。script.sh&; killall script.sh,但不执行任何操作。
bosa djo

我执行script.sh&; #然后我做生意;killall script.sh并不会杀死script.sh
博莎·德约(Dasa Djo)2016年

1
问题可能是脚本收到了信号,但是在处理睡眠程序之前正在等待睡眠程序结束。尝试./script.sh & sleep 1 && kill -- -$(pgrep script.sh)将终止信号也发送到脚本的子进程。
zuazo

@zuazo您应该添加这个有趣和重要的信息,你的答案:)

1
很好,博莎·德约。我在答案中添加了您的替代解决方案;-)
zuazo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.