使用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本身连接到终端后,这才起作用。