16

在子/后台进程中运行时,我无法捕获信号。

这是我的简单 bash 脚本:

#!/bin/bash

echo "in child"

trap "got_signal" SIGINT

function got_signal {
  echo "trapped"
  exit 0
}

while [ true ]; do
    sleep 2
done

当运行这个和以后做

kill -SIGINT (pid)

一切都按预期工作,它打印trapped并退出。

现在,如果我从这样的父脚本启动相同的脚本:

#!/bin/bash

echo "starting the child"

./child.sh &

然后孩子不再捕获信号......?

更改为使用 SIGTERM 而不是 SIGINT 后,它似乎工作正常......?

4

2 回答 2

14

OSX 上的bash手册页(但在其他版本中应该相同)对信号处理有这样的说法:

运行的非内置命令bash将信号处理程序设置为 shell 从其父级继承的值。当作业控制无效时,异步命令会忽略SIGINT这些SIGQUIT继承的处理程序。

进一步,在trap命令下:

进入 shell 时忽略的信号不能被捕获或重置。

由于脚本默认情况下不使用作业控制,这意味着您正在谈论的情况。

于 2011-04-13T00:42:10.710 回答
4

根据您的说明:

Signals ignored upon entry to the shell cannot be trapped or reset.

我注意到 ZSH 不会忽略父进程和子进程之间来回发送的信号,但 bash 会。这是我自己发布的问题:

捕获 CHLD 信号 - ZSH 有效,但 ksh/bash/sh 无效?

于 2012-03-05T00:38:01.450 回答