首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在python中使用pexpect获得子进程的自发输出

如何在python中使用pexpect获得子进程的自发输出
EN

Stack Overflow用户
提问于 2010-11-18 04:25:48
回答 2查看 8.3K关注 0票数 6

这与我的另一篇文章multithreading issue with wx.TextCtrl (or underlying GTK+)有关,在纠正了从主线程调用图形用户界面交互后,我发现它又遇到了管道阻塞缓冲问题。那么,如何从subprocess.stdout获得自发输出呢?

简而言之,目前我正在使用subprocess.popen启动一个外部长时间运行的程序。

代码语言:javascript
复制
    launchcmd=["EXTERNAL_PROGRAM_EXE"]
    p = subprocess.Popen(launchcmd, stdin=subprocess.PIPE, 
            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    self.outputThread = BashProcessThread(p.stdout.readline)
    self.outputThread.start()
    # wx.TextCtrl is used to make input/output
    self.textctrl = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER|wx.TE_MULTILINE)

我使用一个单独的线程来读取后台程序的stdout,并使用"wx.CallAfter“进行回调。

代码语言:javascript
复制
class BashProcessThread(threading.Thread):
    def __init__(self, readlineFunc, textctrl):
        threading.Thread.__init__(self)
        self.readlineFunc = readlineFunc

    def run(self):
        while True:
           line = self.readlineFunc()
           wx.CallAfter(textctrl.AppendText(line))

上面的代码打印子进程日志消息block-hanging-block (而不是自发地逐行打印),最糟糕的是,剩余的5-6行日志消息无法及时打印,直到用户发送下一个输入。

从我以前的帖子中,我了解到有pty和pexpect,这可能会使子进程认为它与伪tty交互。但是应该如何使用pexpect,特别是考虑到后台进程是一个长期的、独立运行的任务?

例如,如果我使用

代码语言:javascript
复制
child=pexpect.spawn(launchcmd)

如何获得子流程的输出和输入,以便使用wx.TextCtrl打印输出,并使用wx.TextCtrl将用户输入转发给子流程?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-18 05:22:16

你有没有尝试过这样的东西:

代码语言:javascript
复制
child = pexpect.spawn(launchcmd)
while True:
    try:
        child.expect('\n')
        print(child.before)
    except pexpect.EOF:
        break
票数 13
EN

Stack Overflow用户

发布于 2014-06-12 00:41:04

我发现这两种方法可以很好地获得实时输出。

如果您不想使用该选项进行用户交互,例如在后台进程中:

代码语言:javascript
复制
child = pexpect.spawn(launchcmd)
child.logfile = sys.stdout
child.expect(pexpect.EOF)
child.close()

如果您没有使用后台进程,并且希望能够与程序交互(如果它提示您的话)。这里发生的情况是,您进入交互模式,pexpect直接写入屏幕。当程序到达末尾时,它会抛出一个OSError。

代码语言:javascript
复制
child = pexpect.spawn(launchcmd)
try:
    child.interact()
except OSError:
    pass
child.close()    
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4208820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档