Python子进程永远不会退出并继续在输出中提供空字符串

时间:2011-03-28 07:17:32

标签: python subprocess stdout stderr

所以,我一直面临着为我正在编写的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='')

1 个答案:

答案 0 :(得分:1)

while p.returncode is None or p.stdout.closed or p.stderr.closed:
任何条件为真时,

循环。您可能只想检查returncode(以及每次迭代中的poll)。