1

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

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

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

我修改了我的子脚本,需要 30 秒才能完成,我观察到在向 sh1 发出 SIGTERM 后,大约需要 30 秒才能终止。

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

父脚本中的信号处理。

function clean_up()
{   
  //Do the cleanup
}

trap "clean_up $$; exit 0" TERM
4

1 回答 1

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。

于 2015-10-21T16:41:19.180 回答