繁体   English   中英

python subprocess:使用subprocess.PIPE时输出顺序的变化

[英]python subprocess: order of output changes when using subprocess.PIPE

当我编写一个名为outer.py的python脚本时

p = subprocess.Popen(['./inner.py'])
print('Called inner.py without options, waiting for process...')
p.wait()
print('Waited for inner.py without options')

p = subprocess.Popen(['./inner.py'], stdout=subprocess.PIPE)
print('Called inner.py with PIPE, communicating...')
b_out, b_err = p.communicate()
out = b_out.decode('utf8')
print('out is "{}"'.format(out))

并且包含inner.py

print("inner: Echoing Hallo")
p = subprocess.Popen(['echo', 'hallo'])
print("inner: Waiting for Echo to finish...")
p.wait()
print("inner: Waited for Echo")

从终端调用outer.py时我得到以下内容:

Called inner.py without options, waiting for process...
inner: Echoing Hallo
inner: Waiting for Echo to finish...
hallo
inner: Waited for Echo
Waited for inner.py without options

Called inner.py with PIPE, communicating...
out is "hallo
inner: Echoing Hallo
inner: Waiting for Echo to finish...
inner: Waited for Echo
"

为什么在使用stdout=subprocess.PIPE inner.py调用inner.py时,“hallo”是否出现在捕获的输出中的“inner:Echoing Hallo”之前?

我猜想,由于某种原因(与管道与ttys相关,请参阅此注释 ), inner.py Python进程的输出在您第一次调用它时是无缓冲的,并在第二次调用它时进行缓冲。 第一次,使用无缓冲输出,您将获得写入tty的预期顺序的结果。 第二次,通过缓冲, echo命令的输出首先被刷新(因为echo运行并终止),然后当python终止时, inner.py进程的所有输出inner.py显示出来。 如果禁用inner.py输出缓冲, inner.py在两种情况下都应获得相同的输出。

通过设置PYTHONUNBUFFERED环境变量,或通过使用-u开关调用python,或者在Python 3上每次print (或print(..., flush=True)后显式调用sys.stdout.flush()禁用输出缓冲。

管道和ttys的行为之间的区别似乎是stdio一般行为 :输出到ttys是行缓冲的(所以,在你的代码中,它逐行读取,它似乎是无缓冲的),而输出到管道是缓冲的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM