Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用pexpect在python中获得子进程的自发输出_Python_Multithreading_Wxpython_Pipe_Pexpect - Fatal编程技术网

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

如何使用pexpect在python中获得子进程的自发输出,python,multithreading,wxpython,pipe,pexpect,Python,Multithreading,Wxpython,Pipe,Pexpect,这与我的另一篇文章有关,在更正了从主线程调用GUI交互后,我发现它再次涉及到管道块缓冲问题。那么,如何从subprocess.stdout获得自发输出呢 简而言之,目前我正在使用subprocess.popen启动一个外部长时间运行的程序 launchcmd=["EXTERNAL_PROGRAM_EXE"] p = subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.P

这与我的另一篇文章有关,在更正了从主线程调用GUI交互后,我发现它再次涉及到管道块缓冲问题。那么,如何从subprocess.stdout获得自发输出呢

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

    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)
我使用一个单独的线程读取后台程序的标准输出,并使用“wx.CallAfter”进行回调

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))
上面的代码打印出子流程日志消息块挂起块(而不是自发地逐行打印),最糟糕的是,在用户发送下一个输入之前,剩余的5-6行日志消息无法及时打印

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

e、 如果我用

child=pexpect.spawn(launchcmd)

如何获取子流程的输出和输入,以便可以使用wx.TextCtrl打印输出,还可以使用wx.TextCtrl将用户输入转发到子流程?

您是否尝试过以下方法:

child = pexpect.spawn(launchcmd)
while True:
    try:
        child.expect('\n')
        print(child.before)
    except pexpect.EOF:
        break

我发现这两种方法对于获得实时输出非常有效

如果不希望用户交互选项,如在后台进程中:

child = pexpect.spawn(launchcmd)
child.logfile = sys.stdout
child.expect(pexpect.EOF)
child.close()
如果您没有使用后台进程,并且希望能够与程序交互(如果它提示您)。这里发生的是,您进入交互模式,pexpect直接写入屏幕。当程序到达结束/EOF时,抛出一个操作错误

child = pexpect.spawn(launchcmd)
try:
    child.interact()
except OSError:
    pass
child.close()    

我花了整整30分钟来尝试一个spawn的所有读取命令。从来没见过以前的房子。我想一个更优雅的解决方案是使用
child.logfile
属性。