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

我的问题是:1)当python解释器现在由init进行父代操作时,python解释器如何将SIGINT发送给孙子; 2)我如何以编程方式杀死孙子。我已经尝试过p.send_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会向其发送SIGINT。为此,您需要了解孙子的PID。没有一个简单的方法来获得它。您的子进程可能已经产生了十几个自己的子进程,他们可能已经产生了更多的子进程,依此类推。

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

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

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

08-18 05:13