Python - 同时捕获Popen的stdout并在控制台显示?
我想要从一个运行时间比较长的程序中获取输出,这个程序是通过 subprocess.Popen(...)
启动的,所以我使用了 stdout=PIPE
这个参数。
不过,因为这个程序运行时间比较长,我还想把输出显示到控制台上(就像我没有使用管道一样),这样可以让使用这个脚本的人知道程序还在继续工作。
这样做有可能吗?
谢谢。
5 个回答
2
S. Lott的评论提到了使用子进程获取实时输出和在Python中实时拦截另一个进程的标准输出这两个链接。
我很好奇,Alex在这里的回答和他在问题1085071中的回答为什么不一样。我对这两个问题中提到的答案做了一些简单的小实验,结果都不错……
我根据Alex上面的回答去看了wexpect,但我必须说,看完代码里的评论后,我对使用它的感觉并不好。
我想这里的一个大问题是,什么时候pexpect/wexpect会成为内置的工具库之一呢?
5
你长时间运行的子进程可能会导致输出到控制台的内容不流畅,体验很糟糕。我建议你考虑使用pexpect(在Windows上可以用wexpect)来解决这个缓冲问题,这样可以让子进程的输出更加平滑和规律。例如(在几乎所有类Unix系统上,安装好pexpect后):
>>> import pexpect
>>> child = pexpect.spawn('/bin/bash -c "echo ba; sleep 1; echo bu"', logfile=sys.stdout); x=child.expect(pexpect.EOF); child.close()
ba
bu
>>> child.before
'ba\r\nbu\r\n'
ba和bu之间的输出会有合适的时间间隔(大约一秒)。注意,这里的输出没有经过正常的终端处理,所以回车符会保留在里面——如果你需要用\n
作为行结束符,你需要自己处理这个字符串(只需简单地用.replace
替换一下就可以了!)。不经过处理是很重要的,特别是当子进程向标准输出写入二进制数据时,这样可以确保所有数据都保持完整!
1
你能不能直接把它从管道里读出来,然后用print
打印出来呢?