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

1 投票
4 回答
1197 浏览
提问于 2025-04-15 14:39

我可以把回车符转换成换行符。不过,问题在于我想让这个过程几乎是“实时”的。如果进度条的值只有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

好的,谢谢!我会关注一下pexpect这个库。
不过我发现还有一种跨平台的方法可以做到这一点:就是用PyQt4和QProcess。虽然这并不一定适用于所有程序,但对于Qt4的前端应用来说,这确实是个不错的选择 :)

1

根据我的经验,使用缓冲区会让你遇到很多麻烦。原因是标准的C库会检测到标准输出(stdout)没有连接到终端,这样就会使用更多的缓冲区。你对此没有办法,只能修改mplayer的源代码。

不过,如果你使用python-pexpect,它会用伪终端来启动你的子进程,这样C库就会认为它连接到了终端,从而不会重置缓冲区。

另外,做这种事情时很容易导致子进程出现死锁,这也是python-pexpect能够解决的另一个问题。

2

在Windows以外的地方,我总是推荐使用pexpect,而在Windows上则推荐wexpect。当你需要“打破缓冲区”,并且想要几乎实时地读取子进程的输出时,这两个工具非常有用。因为你运行的子进程在输出到终端和其他地方时,通常会以不同的方式处理输出(这是C语言运行库的正常行为),所以你需要让它相信自己是在输出到一个终端,而不是你的程序。这就是pexpect的作用,它通过更底层的pty模块创建一个伪终端。我其实很惊讶wexpect在Windows上也能做到类似的事情,虽然偶尔会有些小问题,但它看起来也能正常工作;-)。

撰写回答