SIGTERM 信号动作混淆

SIGTERM signal handling confusion

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

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

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

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

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

parent 脚本中的信号处理。

function clean_up()
{   
  //Do the cleanup
}

trap "clean_up $$; exit 0" TERM

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

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

然后sh1会捕捉到信号什么都不做,直到sh2完成,然后才会执行trap。如果您希望陷阱在信号发送后立即触发,您可以 运行 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。