子流程.Popen用python提供实时反馈

2024-04-19 00:35:34 发布

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

我在python脚本中有一个命令行应用程序,该应用程序当前正在后台运行“blind”。如果我从命令行,mac或PC上运行这个命令,我会得到应用程序运行的实时读数,因为它运行40分钟以上,并在运行时报告各种不同的信息。目前,正如我所说的,它是盲目运行的,在python的读出器上给了我所有的信息,但我希望它本质上打开一个命令行并运行,这样我就可以实时看到所有的信息,但我找不到这样做的方法。这是我当前使用subprocess.Popen的代码。还有别的办法吗?在

command1 = transporterLink + " -m verify -f " + indir1 + " -u " + username + " -p " + password + " -o " + indir1 + "\\VerifyLog.txt -s " + provider1 + " -v eXtreme"
        process = subprocess.Popen(command1, stdout=subprocess.PIPE, shell=True)

Tags: 命令行命令脚本程序运行信息应用程序mac后台
2条回答

我通过修改Mikes answer中的这一部分开始工作,但是唯一的问题是当应用程序结束并且输出完成打印行时,python就会冻结。有什么想法为什么?在

def onRun(self, event):
    """"""
    command1 = transporterLink + " -m verify -f " + indir1 + " -u " + username + " -p " + password + " -o " + indir1 + "\\VerifyLog.txt -s "
+ provider1 + " -v eXtreme"
    master, slave = pty.openpty()
    process = Popen(command1, shell=True, stdin=PIPE, stdout=slave, stderr=slave, close_fds=True)
    stdout = os.fdopen(master)
    while True:
        line = stdout.readline()
        wx.Yield()
        print line.rstrip()
        if not line:
            break
    process.wait()

我几年前写过这篇文章,但我觉得我的标题不太好:

基本上你需要重定向stdout。我通常会这样做:

class RedirectText:
    def __init__(self,aWxTextCtrl):
        self.out=aWxTextCtrl

    def write(self,string):
        self.out.WriteText(string)

然后在我实际的wx类中,我在init中执行如下操作:

^{pr2}$

然后,当您调用子流程时,您将执行如下示例所示的操作:

def pingIP(self, ip):
    proc = subprocess.Popen("ping %s" % ip, shell=True, 
                            stdout=subprocess.PIPE) 
    print
    while True:
        line = proc.stdout.readline()                        
        wx.Yield()
        if line.strip() == "":
            pass
        else:
            print line.strip()
        if not line: break
    proc.wait()

注意wx.产量()打电话。这允许wxPython在将行打印到stdout时进行更新,stdout已重定向到文本控件。在

下面是一个分类示例:

import subprocess
import sys
import wx

class RedirectText:
    def __init__(self,aWxTextCtrl):
        self.out=aWxTextCtrl

    def write(self,string):
        self.out.WriteText(string)

########################################################################
class MyFrame(wx.Frame):
    """"""

    #                                   
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Test")
        panel = wx.Panel(self)
        log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
                          style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
        btn = wx.Button(panel, label="Run")
        btn.Bind(wx.EVT_BUTTON, self.onRun)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        panel.SetSizer(sizer)

        self.redir=RedirectText(log)
        sys.stdout=self.redir

    #                                   
    def onRun(self, event):
        """"""
        command1 = transporterLink + " -m verify -f " + indir1 + " -u " + username + " -p " + password + " -o " + indir1 + "\\VerifyLog.txt -s " + provider1 + " -v eXtreme"
        process = subprocess.Popen(command1, stdout=subprocess.PIPE, shell=True)
        while True:
            line = process.stdout.readline()
            wx.Yield()
            print line
            if not line:
                break
        process.wait()

#                                   
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    frame.Show()
    app.MainLoop()

相关问题 更多 >