使用 subprocess 执行另一个脚本,如何实时输出?

2020-04-23 10:18:10 +08:00
 sunzy

脚本 1,负责输出


for i in range(1, 10):
    print(i)
    time.sleep(1)

脚本 2,用 subprocess 执行脚本 1,获取 stdout 并输出

import subprocess

proc = subprocess.Popen("python3 ./test1.py", shell=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

while True:
  line = proc.stdout.readline()
  if not line:
    break
  print(line.rstrip())

期望的是实时输出,结果是一直等到脚本 1 执行完了才整体输出所有的内容

stackoverflow 上有一篇Non-blocking read on a subprocess.PIPE in python ,我试了线程和 fcntl,还是原样

本人小白,求大神~~

5319 次点击
所在节点    Python
30 条回复
ipwx
2020-04-23 14:48:29 +08:00
我知道了你是不是要处理 ffmpeg 的进度输出。那个没换行,所以要么是 \b 退格,要么是 \r 回到行首。所以没有 \n 你之前用 readline 搞不定很正常。像我一般用 .read 手动处理界定符,真注意不到这个。
mathzhaoliang
2020-04-23 14:53:48 +08:00
我会这样写

```python
process = subprocess.Popen(
ffmpeg_command,
shell=True,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)

_, err = process.communicate()
if process.returncode:
print(type(err), err)
raise IOError("FFMPEG error: " + err.decode("ascii"))
```
FaiChou
2020-04-23 15:10:51 +08:00
应该是相同的问题,我在 node 中遇到过 https://www.v2ex.com/t/645816#reply2
sunzy
2020-04-23 15:20:14 +08:00
@ipwx 是的,是要监控进度输出,用.read(n)怎么读取正好一行的数据呢?
sunzy
2020-04-23 15:32:01 +08:00
@mathzhaoliang 这样写只能获取最后的信息吧
ipwx
2020-04-23 20:46:52 +08:00
@sunzy 基本思路:

buf = b''

def handle(cnt):
....buf += cnt
....while True:
........pos = buf.find(b'\n‘)
........if pos <= -1:
............break
........handle_line(buf[:pos])
........buf = buf[pos:]

def handle_line(line):
....do what you want to do

while not eof:
....handle(read(n))
if buf:
....handle_line(buf)
ipwx
2020-04-23 20:47:30 +08:00
就是用个缓冲区自己解析一下。上面是伪代码,不是真的能运行的代码。
sunzy
2020-04-24 09:45:42 +08:00
@ipwx 赞!
yyfeng88625
2020-04-24 12:08:35 +08:00
使用 sh 库就好,自己写里面很多坑的
https://amoffat.github.io/sh/tutorials/real_time_output.html
sunzy
2020-05-03 22:20:28 +08:00
@yyfeng88625 这个库不错,学习了,感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/665236

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX