【发布时间】:2011-03-28 07:17:32
【问题描述】:
所以,在我正在编写的 python 应用程序中使用子进程时,我遇到了一个问题。为了说明问题,我编写了这个小脚本,很好地复制了我的问题。
from __future__ import print_function
import subprocess as sp
from select import select
p = sp.Popen(['ls'], stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)
p.stdin.close()
while p.returncode is None or p.stdout.closed or p.stderr.closed:
# print('returncode is', p.returncode)
available_readers = select([p.stdout, p.stderr], [], [], 2.0)[0]
for r in available_readers:
print(r.read(1))
# output_display.insert(tk.END, r.read(1))
当然,我们都知道ls命令在打印一些东西到stdout(或者可能是stderr)后立即存在,但上面的脚本永远不存在。
从上面脚本的最后一行(注释)可以看出,我必须将子进程中的内容放入一个 tk 文本组件中。所以,我不能使用像.communicate 和其他阻塞调用这样的方法,因为我需要运行的命令需要很长时间,而且我需要(几乎)实时显示输出。 (当然,在运行 Tk 时,我必须在单独的线程中运行它,但那是另外一回事。
所以,我无法理解为什么这个脚本永远不会退出。它会一直打印空字符串(在ls 命令的预期输出之后)。
请指教。我在 ubuntu 10.10 上运行 python 2.6.6
编辑:这是上述脚本的有效版本
from __future__ import print_function
import subprocess as sp
from select import select
p = sp.Popen(['ls'], stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)
p.stdin.close()
while p.poll() is None:
# print('returncode is', p.returncode)
available_readers = select([p.stdout, p.stderr], [], [], 2.0)[0]
for r in available_readers:
print(r.read(1), end='')
# output_display.insert(tk.END, r.read(1))
print(p.stdout.read(), end='')
print(p.stderr.read(), end='')
【问题讨论】:
标签: python subprocess stdout stderr