使用python3 / linux / bash:
gnr@localhost: cat my_script
#!/usr/bin/python3
import time, pexpect
p = pexpect.spawn('sleep 123')
p.sendintr()
time.sleep(1000)
按原样运行时效果很好(即my_script
启动sleep 123
子进程,然后发送SIGINT
,这会导致sleep 123
)。但是,当我将my_script
作为孙子进程进行后台处理时,它不再能够终止sleep 123
命令:
gnr@localhost: (my_script &> /dev/null &)
任何人都知道这里发生了什么/如何更改my_script
或pexpect
以便仍然能够SIGINT
向其子进程发送信息?
我认为这与后台操作有关,导致没有控制终端,也许我需要创建一个新的pty?
更新:从来没有想过如何创建一个pty(虽然ssh&#ing进入localhost并且-t选项工作) - 最后做一个os.fork()来构建一个子进程而不是{{1这是有效的,因为(我猜测)控制终端没有立即关闭。
答案 0 :(得分:1)
你确定这个过程没有被杀死吗?我希望它在进程列表中显示<defunct>
,因为生成的进程现在位于sleep
中,并且在sleep
完成之前无法完成正确的清理。 <defunct>
进程已被杀死,只是他们的父母没有进行清理。
如果你能以某种方式修改你的代码,以便父实际经历正常处理并关闭子(spawn),那么它应该工作。虽然笨拙可能有用:
import time, pexpect, os
newpid = os.fork()
if newpid == 0:
# Child
p = pexpect.spawn('sleep 123')
p.sendintr()
else:
# parent
time.sleep(1000)
在这种情况下,我们fork
我们自己的孩子处理产卵并进行杀戮。由于我们的孩子没有自己阻挡sleep
,它优雅地退出,包括正确清理它杀死的过程。同时,主(父)线程正在等待sleep
在您发表评论后,我发现虽然我在bash提示符下将我的脚本放在后台,但我并没有像你那样做。
我正在使用
(expecttest.py > /dev/null 2>&1 &)
将stdin和stdout重定向到&gt; / dev / null并将进程置于后台。
如果我使用原始代码而不是执行sendintr
而是使用命令shell中的调用来执行terminate
它可以正常工作。 sleep 123
似乎没有回应pexpect在这种情况下做的事情。