为什么子进程的管道输出对Python如此不可靠? [英] Why is piping output of subprocess so unreliable with Python?

查看:90
本文介绍了为什么子进程的管道输出对Python如此不可靠?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(对于Windows)

(Windows)

我编写了一些Python代码,调用了程序SoX(子过程模块),如果指定这样做,它将在STDERR上输出进度.我想从输出中获取百分比状态.如果我不是从Python脚本中调用它,它将立即启动,并且平滑过渡直到100%.

I wrote some Python code that calls the program SoX (subprocess module), which outputs the progress on STDERR, if you specify it to do so. I want to get the percentage status from the output. If I call it not from the Python script, it starts immediately and has a smooth progression till 100%.

如果我从Python脚本中调用它,它将持续几秒钟直到启动,然后在慢速输出和快速输出之间交替.尽管我逐个字符地阅读char,但有时还是会拉出很大的一块.所以我不明白为什么有时候我可以看着角色一个接一个地变得更多. (顺便说一下,它在我的测试中生成了15KiB的数据.)

If I call it from the Python script, it lasts a few seconds till it starts and then it alternates between slow output and fast output. Although I read char by char sometimes there RUSHES out a large block. So I don't understand why at other times I can watch the characters getting more one by one. (It generates 15KiB of data in my test, by the way.)

我已经使用mkvmerge和mkvextract测试了相同的内容.他们也输出百分比.在那里读STDOUT很顺利.

I have tested the same with mkvmerge and mkvextract. They output percentages, too. Reading STDOUT there is smooth.

这太不可靠了!如何使sox的stderr流的读取更平滑,也许可以防止开始时出现延迟?

This is so unreliable! How can I make the reading of sox's stderr stream smoother, and perhaps prevent the delay at the beginning?

我的通话方式和阅读方式:

How I call and read:

process = subprocess.Popen('sox_call_dummy.bat', stderr = subprocess.PIPE, stdout = subprocess.PIPE)
while True:
    char = process.stderr.read(1).encode('string-escape')
    sys.stdout.write(char)

推荐答案

根据与此密切相关的线程:

As per this closely related thread: Unbuffered read from process using subprocess in Python

process = subprocess.Popen('sox_call_dummy.bat', 
                stderr = subprocess.PIPE, bufsize=0)
while True:
    line = process.stderr.readline()
    if not line: 
        break
    print line

由于您没有阅读stdout,所以我认为您不需要管道.

Since you aren't reading stdout, I don't think you need a pipe for it.

如果您要尝试像原始示例一样逐个读取char,请尝试每次添加一次刷新:

If you want to try reading char by char as in your original example, try adding a flush each time:

sys.stdout.write(char)
sys.stdout.flush()

每次编写时刷新标准输出都是手动禁用python进程的缓冲:python.exe -u <script>或设置env变量PYTHONUNBUFFERED=1

Flushing the stdout every time you write is the manual equivalent of disabling buffering for the python process: python.exe -u <script> or setting the env variable PYTHONUNBUFFERED=1

这篇关于为什么子进程的管道输出对Python如此不可靠?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆