我试图了解为什么在此设置下信号无法正确通过。 简单测试,我有一个python脚本,注册了一个sigterm处理程序,并在获取时进行打印。如果运行并发送TERM,我已经验证了此工程。
但是,我恰巧是使用useShell = True将其作为python子进程运行。 useShell使用/ bin / sh -c ...启动命令。
如果我这样做,它实际上也可以正常工作:
$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
$ kill 6207
signum 15
但是,我有执行链接命令的脚本,即/foo/bar.sh;。 some_other_script.py。在这种情况下,信号 not 不会传递给最终脚本:
$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
$ kill 8015
如果我尝试&&而不是; 我试图了解这里发生的事情,以及是否有一种方法可以使信号通过链传递。 观点:脚本运行多链命令的主要原因是因为第一个命令设置了一些环境供第二个命令使用。
signal_test.py:
import time
import signal
import sys
def handler( signum, frame ):
print( "signum %d\n" % signum )
sys.exit(signum)
signal.signal( signal.SIGTERM, handler )
time.sleep(60)
答案 0 :(得分:2)
让我解释一下细节。
在shell中运行命令时,shell将创建一个新的进程组。该组将包含命令中的所有进程。 pgid与Leader进程的pid相同。
进程组表示单词multi-task中的任务,shell可以使用bg(^ Z)/ fg在组之间进行切换。外壳程序(实际上是另一个故事)生成的所有信号(如^ C)都将发送到整个组,而不是领导程序。
答案很明显,当命令无法由单个进程处理时,shell将创建多个进程。
$/bin/sh -c "python ~/tmpcode/signal_test.py" &
[8] 6207
发出单个命令,因此子外壳程序本身(/bin/sh
)成为python
。请注意,即使只有一个进程,仍然会有一个包含唯一进程的新进程组。
$ /bin/sh -c "echo foo; python ~/tmpcode/signal_test.py" &
[8] 8015
发出两个命令,单个进程无法完成任务,因此需要多个进程:
/bin/sh
echo
python
创建了包含这三个过程的过程组。
使用
kill <SIGNAL> -<pgid>
pgid前面的减号是必不可少的。