当我编写一个名为outer.py
的包含
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))
包含<{p}的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
"
为什么在用inner.py
调用stdout=subprocess.PIPE
时,“hallo”是否出现在捕获输出中的“inner:Echoing Hallo”之前?
答案 0 :(得分:3)
我猜想,出于某种原因(与管道与ttys相关,请参阅this comment),inner.py
Python进程的输出在您第一次调用它时是无缓冲的,并且缓冲了第二次你打电话。第一次,使用无缓冲输出,您将获得写入tty的预期顺序的结果。第二次,通过缓冲,echo
命令的输出首先被刷新(因为echo
运行并终止),然后inner.py
进程的所有输出立即显示,当python
终止时。如果禁用inner.py
的输出缓冲,则在两种情况下都应获得相同的输出。
通过设置PYTHONUNBUFFERED
环境变量,或使用-u
开关调用python,或在每sys.stdout.flush()
之后显式调用print
(或{{}来禁用输出缓冲1)}在Python 3)上。
管道和ttys的行为之间的区别似乎是general behaviour of stdio
:输出到ttys是行缓冲的(所以,在你的代码中,它逐行读取,它似乎是无缓冲的),而管道的输出是缓冲的。