bash 子后台进程中的陷阱信号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5643132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:46:47  来源:igfitidea点击:

Trap signal in child background process

bashsignalschild-processsigintbash-trap

提问by Matthieu

I am unable to trap a signal when running in a child / background process.

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

Here is my simple bash script :

这是我的简单 bash 脚本:

#!/bin/bash

echo "in child"

trap "got_signal" SIGINT

function got_signal {
  echo "trapped"
  exit 0
}

while [ true ]; do
    sleep 2
done

When running this and later do

运行这个和以后做

kill -SIGINT (pid)

Everything works as expected, it prints 'trapped' and exits.

一切都按预期工作,它打印“被困”并退出。

Now, if I start the same script from a parent script like this :

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

#!/bin/bash

echo "starting the child"

./child.sh &

Then the child does not trap the signal anymore.... ?

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

After changing to use SIGTERM instead of SIGINT, it seems to be working correctly... ?

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

采纳答案by geekosaur

The bashmanpage on OSX (but it should be the same in other versions) has this to say about signal handling:

bashOSX 上的联机帮助页(但在其他版本中应该相同)有关于信号处理的说明:

Non-builtin commands run by bashhave signal handlers set to the values inherited by the shell from its parent. When job control is not in effect, asynchronous commands ignore SIGINTand SIGQUITin addition to these inherited handlers.

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

and further on, under the trapcommand:

进一步,在trap命令下:

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

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

Since scripts don't use job control by default, this means the case you're talking about.

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

回答by Reza Toghraee

Per your note:

根据您的说明:

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

I have noticed that ZSH does not ignore the signals sent back and forth between parent and child process, but bash does. Here's the question I posted myself:

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

Trapping CHLD signal - ZSH works but ksh/bash/sh don't?

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