开发者

Python subprocess never exits and keeps giving empty strings in output

开发者 https://www.devze.com 2023-02-20 00:06 出处:网络
So, I have been facing a problem with using subprocess for a python app i am writing. To illustrate the problem, I wrote this small script that replicates my p开发者_开发问答roblem pretty well.

So, I have been facing a problem with using subprocess for a python app i am writing. To illustrate the problem, I wrote this small script that replicates my p开发者_开发问答roblem pretty well.

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))

Ofcourse, we all know that ls command exists immediately after printing some stuff to stdout (or may be stderr), but the above script never exists.

As you can see from the last line (comment) in the above script, I have to put the content from the subprocess into a tk text component. So, I can't use methods like .communicate and other blocking calls as the command I need to run takes a long time and I need to show the output (almost) realtime. (Ofcourse, I have to run this in a separate thread when running Tk, but that's something else).

So, I am unable to understand why this script never exits. It keeps printing empty strings forever (after the expected output of the ls command).

Please advise. I am running python 2.6.6 on ubuntu 10.10

Edit: Here's the version of the above script that works

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='')


while p.returncode is None or p.stdout.closed or p.stderr.closed:

loops while any of the conditions is true. You probably meant to check just returncode (and poll in every iteration).

0

精彩评论

暂无评论...
验证码 换一张
取 消