【问题标题】:How to catch SIGINT within a Bash subshell如何在 Bash 子外壳中捕获 SIGINT
【发布时间】:2022-01-06 15:54:39
【问题描述】:

如果我在命令行运行一个命令,例如 grep,然后点击 ^C,该命令会被正确终止(我认为是 SIGINT)。如果我在后台运行 grep,然后在其 PID 上运行 kill SIGINT,它同样会被终止。 但是如果我在脚本中并从脚本在后台运行 grep,获取它的 PID,然后使用 'kill -s SIGINT $PID',grep 不会被杀死。为什么?如果我使用 SIGTERM 而不是 SIGINT,kill 确实 起作用。

#!/bin/bash
grep -rqa shazam /usr &
PID=$!
kill -s SIGINT $PID

即使我将 grep 放在子进程中,前面有一个 SIGINT 处理程序(在子进程中),并使用 SIGINT 命中子进程,也不会调用该处理程序。

#!/bin/bash
( trap 'echo "caught signal"' SIGINT; grep -rqa shazam /usr ) &
PID=$!
kill -s SIGINT $PID

如果我使用 SIGTERM 而不是 SIGINT,则会调用陷阱处理程序 ,但不会中断 grep。如果我将“/bin/kill -s SIGTERM 0”添加到陷阱处理程序,则表明 grep 进程已终止,但此时 grep 已完成其工作。我意识到 Bash 可能对不同的信号有不同的默认行为,但我不明白为什么我的 kill SIGINT 调用与 ^C 不同,为什么陷阱调用适用于 SIGTERM,但不适用于 SIGINT,也不明白为什么 SIGTERM '不立即由子进程处理。

【问题讨论】:

    标签: linux bash signals


    【解决方案1】:

    好吧,通过进一步挖掘,我发现了 3 个问题中的 2 个。当我在脚本中使用 grep 时,shell 告诉它忽略 SIGINT。 Bash 表示它会等待处理信号,直到子命令在某些情况下完成(我目前没有完全遵循),但如果直接使用 pkill 命中 grep 进程,则会立即处理信号。

    【讨论】:

      猜你喜欢
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2013-08-30
      相关资源
      最近更新 更多