信号被捕获的shell脚本不会忽略信号

时间:2020-02-05 17:16:58

标签: linux bash unix process

我正在测试自动化系统,并且提出了行为异常的程序。对于第一个,我已经遇到了一些意外的行为。

    trap "echo No thanks" INT                            

    echo Let me just chill for $1 sec  
    sleep $1                                     
    echo All finished

观察到的行为:

  • 发送SIGINT会导致显示“不,谢谢”,显然睡眠会立即中断,并且此后还会立即显示“所有完成”。
  • 无论信号是单独发送还是使用键盘ctrl + c执行,
  • 行为都是相同的。
  • 如果睡眠是背景,我们会wait观察到相同的行为。

预期的行为:

  • 将SIGINT发送到该进程将导致在睡眠运行期间一直打印“不,谢谢”,然后在睡眠完成后退出之前将打印“所有完成”。
  • 如果休眠是后台运行,则发出键盘ctrl + c会将SIGINT发送到进程组,该组将包括休眠,因此应过早停止它。 / li>

问题:

  • 如何获得所需的行为?
  • 为什么它的行为确实如此(与我的预期不同)?

该问题本质上是this的重复,但该答案中没有令人满意的解释。

1 个答案:

答案 0 :(得分:2)

当前:

  1. bash等待sleep退出
  2. bashsleep收到签名
  3. sleep死了
  4. bash完成等待并运行陷阱

这会阻止您期望的行为,因为:

  • 您不希望sleep
  • 您不希望bash在运行陷阱之前等待命令完成

要解决此问题,您可以让sleep忽略sigint,并使bash循环运行wait,以便主脚本在ctrl-c之后获得控制权,但是仍然等待sleep完成:

trap 'echo "No thanks"' INT
echo "Let me just chill for $1 sec"
# Run sleep in the background
sleep "$1" &
# Loop until we've successfully waited for all processes
until wait; do true; done
echo "All finished"