SIGTERM信号处理混乱

时间:2015-10-21 15:59:10

标签: bash shell signals sigterm

我正在运行一个调用shell脚本的程序(用于讨论sh1与pid 100)。 该脚本依次调用另一个脚本(用于讨论sh2与pid 101)并等待它完成。 sh2(子脚本)大约需要50秒才能完成。

我调用sh2的方式(/bin/sh2.sh)

在等待孩子完成期间,我尝试终止sh1(使用kill -15 100)。我在sh1中有一个处理函数来处理这个信号。但是,我观察到我的sh1(父脚本)不会被终止,直到孩子完成其工作(50秒),并且只有在此之后才处理此信号。

我修改了我的子脚本,需要30秒才能完成,我发现在将SIGTERM发送到sh1之后,它需要大约30秒才能终止。

这是处理SIGTERM时的行为吗?那是否会被子进程阻止?然后才处理信号。这个过程是否因信号处理而中断?

父脚本中的SIGNAL处理。

function clean_up()
{   
  //Do the cleanup
}

trap "clean_up $$; exit 0" TERM

1 个答案:

答案 0 :(得分:1)

如果sh1调用sh2并等待它完成,则在sh2完成之前它不会运行信号的陷阱。也就是说,如果这是sh1:

#!/bin/sh  
trap 'echo caught signal delayed' SIGTERM
sh2

然后sh1将捕获信号并且在sh2完成之前不执行任何操作,然后它将执行陷阱。如果您希望在发送信号后立即触发陷阱,则可以异步运行sh2并明确等待它:

#!/bin/sh
trap 'echo caught signal' SIGTERM
sh2&
wait

不幸的是,这不会重新进入等待状态。如果你需要继续等待,那真的不可能做到可靠,但你可以接近:

#!/bin/sh
trap 'echo caught signal' SIGTERM
sh2&
(exit 129)   # prime the loop (eg, set $?) to simulate do/while
while test $? -gt 128; do wait; done

这是不可靠的,因为你不能区分自己捕捉信号和信号终止sh2之间的区别。如果你需要这个是可靠的,你应该用一种允许更好地控制信号的语言重写sh1。