Python 如何将SIGINT传递给孙子(以及如何通过编程实现)

Python 如何将SIGINT传递给孙子(以及如何通过编程实现),python,linux,bash,signals,Python,Linux,Bash,Signals,使用linux/bash/python3,我创建了一个孙子进程sleep 123。当我调用p.terminate()时,这会终止子进程(init接管孙子进程sleep 123)。然而,在python解释器中,我仍然可以按Ctrl+C来杀死孙子 我的问题是1)当python解释器现在由init作为父代时,它如何可能向孙子发送SIGINT,以及2)我如何通过编程杀死孙子。我尝试了p.send\u signal(signal.SIGINT),玩stdin=PIPE等,但无法让它工作 gnr@local

使用linux/bash/python3,我创建了一个孙子进程
sleep 123
。当我调用
p.terminate()
时,这会终止子进程(init接管孙子进程
sleep 123
)。然而,在python解释器中,我仍然可以按Ctrl+C来杀死孙子

我的问题是1)当python解释器现在由init作为父代时,它如何可能向孙子发送SIGINT,以及2)我如何通过编程杀死孙子。我尝试了
p.send\u signal(signal.SIGINT)
,玩
stdin=PIPE
等,但无法让它工作

gnr@localhost: python3
Python 3.3.1
>>> from subprocess import PIPE, Popen
>>> p = Popen(['bash', '-c', '(sleep 123)'])

gnr@localhost: ps -AF | grep sleep
gnr 5081 5078 0 26526 1168 6 14:03 pts/26 00:00:00 bash -c (sleep 123)
gnr 5082 5081 0 25228 564  4 14:03 pts/26 00:00:00 sleep 123

>>> p.terminate()

gnr@localhost: ps -AF | grep sleep
gnr 5082    1 0 25228 564  4 14:03 pts/26 00:00:00 sleep 123   #init inherits

>>>        # hits Ctrl+C
KeyboardInterrupt
>>>

gnr@localhost: ps -AF | grep sleep
#grandchild is dead

更新:我最终使用了pexpect(它为您处理了大量的pty和termios内容)。

孙辈仍然将终端作为其标准输入,而不管是否进行了任何修改,因此在终端中按Ctrl-C键都会向其发送信号。要自己做这件事,你需要知道孙子的PID。没有一个简单的方法来获得它;您的子进程可能已经产生了十几个自己的子进程,他们可能已经产生了更多的子进程,等等。现在还不清楚哪一个将是“孙子”

但是,您可以向前台组中的所有进程发送信号

os.kill(-os.getpgid(os.getpid()),signal.SIGINT)

当然,这只有在Python本身连接到终端时才起作用。

在Linux上,向进程发送kill或terminate信号并不会结束其子进程。它们变得孤立,并被init系统进程采用

你可以用这个包裹。你可以用它做类似的事情:

from subprocess import Popen
import psutil

proc = Popen(['bash', '-c', '(sleep 123)'])
parent = psutil.Process(proc.pid)
for child in parent.children(recursive=True):
    child.terminate()

parent.terminate()

如果我在创建子进程时设置了
stdin=PIPE
,我会看到相同的行为,因此我看不到终端在这一点上如何与孙子进程的stdin建立任何连接。你是对的,这不是stdin,而是。谢谢,这有助于我指出我可以使用控制终端杀死孙子进程的事实。