使用python实时解析包含回车的命令行输出进度

时间:2009-09-28 10:13:34

标签: python parsing real-time carriage-return

我可以将回车转换为新行。然而问题是让它几乎“实时”运行。如果progres bar的值只有0和100,那将是非常愚蠢的: - )

此代码立即返回输出:

import subprocess

p = subprocess.Popen(['mplayer', '/home/user/sample.mkv'], stdout=subprocess.PIPE).communicate()[0]
for line in p.splitlines():
    if line.strip():
        print line

4 个答案:

答案 0 :(得分:2)

pexpect除了Windows和Windows上的wexpect之外,当你需要“击败缓冲”并“近乎实时地”读取子进程的输出时,总是我的建议,就像你说的那样。由于您正在运行的子进程最有可能在输出到终端而不是其他任何东西时以不同方式缓冲其输出(因为这是C运行时库的正常行为),您需要诱使它相信它输出到终端而不是而不是你的程序,这就是pexpect实现的目标(通过较低级pty模块构建一个伪终端)。我真的很惊讶wexpect能够在Windows上做同样的事情,但是,虽然偶尔不完美,但它似乎也可以工作; - )。

答案 1 :(得分:1)

根据我的经验,你正在为一个充满痛苦的世界而奋斗。原因是标准C库将检测到stdout未连接到终端并使用更多缓冲。除了破解mplayer的来源,你无能为力。

如果您使用python-pexpect,它将使用伪库来启动您的子进程,C库认为它是终端,并且它不会重置缓冲。

在执行此类操作时,很容易使子进程死锁,这是python-pexpect的另一个问题。

答案 2 :(得分:0)

好的,谢谢!我将继续关注pexpect。 但我发现有cosplatform方法可以做到:PyQt4和QProcess。虽然它不是每个程序的解决方案,但它肯定适合Qt4前端应用程序:)

答案 3 :(得分:-1)

你需要做两件事:

  1. 您必须确保mplayer为每一行刷新输出(应该将进度输出打印到同一行)。

  2. 您必须逐行读取输出。您必须关闭communicate(),然后阅读p.stdin直至EOF,而不是致电p.stdout