Подпроцесс Python никогда не завершается и продолжает выдавать пустые строки на выходе - PullRequest
0 голосов
/ 28 марта 2011

Итак, я столкнулся с проблемой использования подпроцесса для приложения на 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).

Пожалуйста, сообщите. Я использую Python 2.6.6 на Ubuntu 10.10

Редактировать: вот версия вышеуказанного скрипта, которая работает

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 Ответ

1 голос
/ 28 марта 2011
while p.returncode is None or p.stdout.closed or p.stderr.closed:

зацикливается, в то время как любое условий верно. Вы, вероятно, хотели проверить только returncodepoll в каждой итерации).

...