1

我能够将回车转换为新行。然而,问题是让它几乎“实时”运行。如果进度条的值只有 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

4 回答 4

2

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

于 2009-09-28T15:04:19.877 回答
1

根据我的经验,您正在经历一个痛苦的世界。原因是标准 C 库将检测标准输出未连接到终端并使用更多缓冲。除了破解mplayer.

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

在做这种事情时也很容易造成子进程死锁,这是 python-pexpect 解决的另一个问题。

于 2009-09-28T13:07:28.367 回答
0

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

于 2009-10-01T01:20:42.893 回答
-1

你需要做两件事:

  1. 您必须确保mplayer刷新每一行的输出(应该与打印到同一行的进度输出一起发生)。

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

于 2009-09-28T11:26:35.287 回答