Skip to main content
 首页 » 编程设计

python之subprocess.PIPE 增量输出

2025年05月04日16JeffreyZhao

我正在使用 subprocess 模块来运行来自另一个应用程序的命令我知道您可以执行以下操作

import subprocess 
 
app = subprocess(args, stdout=subprocess.PIPE) 
out, err = app.communicate() 
print out 

我希望输出能够像最后一个大 Blob 那样显示出来。想法?

请您参考如下方法:

问题可能是您在子进程中运行的命令缓冲了它的输出:在这种情况下,在 Blender 的回答中,process.stdout.read(1) 不会返回,直到输出子进程的缓冲区已满,导致其被刷新,从而被父进程看到。

参见 this answer和 this one有关缓冲如何影响事物的更多信息。

这里有一些脚本来说明:

# spew.py 
import sys 
import time 
 
for i in range(10): 
    print 'Message no. %d' % i 
    #sys.stdout.flush() 
    time.sleep(1) 

和

# runspew.py 
import subprocess 
import time 
 
start = time.time() 
p = subprocess.Popen(['python', 'spew.py'], stdout=subprocess.PIPE) 
data = p.stdout.read(1) 
print 'Elapsed time to first byte read: %.2f' % (time.time() - start) 
data = p.stdout.read() 
print 'Elapsed time to last byte read: %.2f' % (time.time() - start) 
p.wait() 

现在,将两个脚本放在同一目录中并运行 python runspew.py。你会看到这样的东西:

Elapsed time to first byte read: 10.05 
Elapsed time to last byte read: 10.05 

现在,删除 spew.py 中 sys.stdout.flush() 的注释,然后再次执行 python runspew.py。你现在会看到这样的东西:

Elapsed time to first byte read: 0.02 
Elapsed time to last byte read: 10.04 

请注意 runspew.py 没有改变:只有作为子进程运行的程序改变了。如果您正在运行的程序无法运行无缓冲(或频繁刷新),那么您将不得不使用 expect/unbuffer我链接到的答案。