SIGINT对脚本

时间:2016-03-09 15:13:17

标签: python linux makefile signals posix

我试图通过以两种不同方式启动的脚本来理解我对SIGINT信号的行为。

这是一个简单的python脚本:

import time
while True:
      time.sleep(10000)

如果我在后台启动脚本,请检查pid和ppid(注意它与我的终端相同)并用SIGINT杀死它,它可以工作:

user@host [~] > python script.py &
[1] 19077

user@host [~] > ps axo pid,ppid,command | grep script
19077  1055 python script.py
19093  1055 grep script

user@host [~] > kill -INT 19077
Traceback (most recent call last):                                                                                                                
  File "script.py", line 10, in <module>
    time.sleep(10000)
KeyboardInterrupt
[1]  + exit 1     python script.py

现在,如果我通过Makefile启动它:

user@host [~] > cat Makefile
all:
    python script.py &

user@host [~] > make
python script.py &

user@host [~] > ps axo pid,ppid,command | grep script
19118     1 python script.py
19122  1055 grep script

user@host [~] > kill -INT 19118
user@host [~] > ps axo pid,ppid,command | grep script
19118     1 python script.py
19128  1055 grep script

请注意,现在,它的ppid为1(init,似乎是逻辑)并且它不会被杀死。好像该过程没有收到信号。我改变了我的脚本来自己处理信号:

import time, signal, sys

def signal_handler(signal, frame):
    print 'Killed !'
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

while True:
    time.sleep(10000)

现在这个过程被我写的处理程序杀死了:

user@host [~] > make
python script.py &
user@host [~] > ps axo pid,ppid,command | grep script
19148     1 python script.py
19152  1055 grep script
user@host [~] > kill -INT 19148
Killed !                                                                                                                                          
user@host [~] > ps axo pid,ppid,command | grep script
19158  1055 grep script

所以我的问题是:为什么当ppid为1或使用Makefile启动时,进程不会被SIGINT杀死?我无法理解这种行为,我知道最好的办法就是用SIGTERM来杀死它,因为它几乎就像一个守护进程,但无论如何我想要理解这一点。

在python中,SIGINT信号被转换为KeyboardInterrupt异常,我试图抓住它而没有任何成功。

我在bash中执行了相同的脚本,行为完全相同。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

信号处理程序继承自父进程,正如您自己演示的那样,可以重新定义。所以make要么重新定义它。或者,特别是对于SIGINT,可能有一个逻辑在进程失去stdin或其终端时重新定义处理程序,因为SIGINT通常用于Ctrl-C。没有终端,没有Ctrl-C。