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

发布于 2024-08-06 10:19:14 字数 297 浏览 5 评论 0原文

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

I am able to transform carriage returns into new lines. The problem however is to get it running in nearly 'real time'. It will be quite stupid looking if progres bar only values are 0 and 100 :-)

This code returns output at once:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

反差帅 2024-08-13 10:19:14

pexpect 除 Windows 之外的任何地方,以及 wexpect 在 Windows 上,当您需要“击败缓冲”并“近乎实时”读取子进程的输出时,我始终建议您使用“,正如你所说。由于您正在运行的子进程在输出到终端时与其他任何东西(因为这是 C 运行时库的正常行为)时很可能以不同的方式缓冲其输出,因此您需要欺骗它相信它正在输出到终端而不是而不是你的程序,这就是 pexpect 所实现的(通过通过较低级别的 pty 模块构建伪终端)。事实上,令我惊讶的是 wexpect 能够在 Windows 上执行大部分相同的操作,尽管偶尔不完美,但它似乎也能工作;-)。

pexpect anywhere but Windows, and wexpect on Windows, are always my recommendations when you need to "defeat buffering" and read a subprocess's output "in near real-time", as you put it. Since the subprocess you're running most likely buffers its output differently when it's outputting to a terminal vs. anything else (as that's the normal behavior of the C runtime libraries), you need to trick it into believing it IS outputting to a terminal rather than to your program, and that's what pexpect achieves (by building a pseudo-terminal via the lower-level pty module). I'm actually amazed that wexpect was able to do much the same on Windows, yet, while occasionally imperfect, it does also appear to work;-).

半葬歌 2024-08-13 10:19:14

根据我的经验,你正处于一个充满痛苦和缓冲的世界。原因是标准 C 库将检测到 stdout 未连接到终端并使用更多缓冲。除了破解 mplayer 的源代码之外,您对此无能为力。

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

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

You are in for a world of pain with buffering in my experience. The reason being is that the standard C library will detect stdout isn't connected to a terminal and use more buffering. There is nothing you can do about that except hack the source of mplayer.

If you use python-pexpect though, it will start your subprocess using pseudo-ttys which the C library believes to be a terminal and it won't reset the buffering.

It is very easy to make subprocess deadlock when doing this sort of thing too which is another problem python-pexpect gets over.

﹏半生如梦愿梦如真 2024-08-13 10:19:14

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

Ok, Thanks! I will keep on eye for pexpect.
But I found out that there is cosplatform way to do it: PyQt4 and QProcess. While it is not certainly solution for every program, it certainly fits for Qt4 frontend application :)

洋洋洒洒 2024-08-13 10:19:14

您需要做两件事:

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

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

You need to do two things:

  1. You must make sure that mplayer flushes the output for every line (should happen with progress output that gets printed into the same line).

  2. You must read the output line by line. Instead of calling communicate(), you must close the p.stdin and then read p.stdout until EOF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文