如何使用pexpect从后台进程发送信号

时间:2014-09-17 21:17:56

标签: python linux bash signals pexpect

使用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_scriptpexpect以便仍然能够SIGINT向其子进程发送信息?

我认为这与后台操作有关,导致没有控制终端,也许我需要创建一个新的pty?

更新:从来没有想过如何创建一个pty(虽然ssh&#ing进入localhost并且-t选项工作) - 最后做一个os.fork()来构建一个子进程而不是{{1这是有效的,因为(我猜测)控制终端没有立即关闭。

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在这种情况下做的事情。