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

2024-09-28 21:50:11 发布

您现在位置:Python中文网/ 问答频道 /正文

使用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命令:

^{pr2}$

有人知道这里发生了什么/如何更改my_script或{}以便仍然能够向其子进程发送{}?在

我想这是因为背景导致没有控制终端,也许我需要创建一个新的pty?在

更新:从来没有想过如何创建一个pty(尽管使用-t选项通过ssh连接到localhost中),但最后却执行了一个os.fork操作系统()来后台处理子进程,而不是(my_script &> /dev/null &),这是因为(我猜)控制终端没有立即关闭。在


Tags: bashlocalhost终端time进程mylinuxscript
1条回答
网友
1楼 · 发布于 2024-09-28 21:50:11

你确定进程没有被终止吗?我希望它在进程列表中显示<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提示符下把我的脚本放在后台,但我并没有像你那样做。在

我在用

^{pr2}$

这会将stdin和stdout重定向到>;/dev/null,并将进程置于后台。在

如果我使用您的原始代码,而不是执行sendintr,而是使用命令shell中的调用执行terminate。在这种情况下,sleep 123似乎没有响应pexpect正在做的事情。在

相关问题 更多 >