2013-05-29 5 views
1

Я прочитал и пробовал по 8 различным методам ответа на несколько вопросов об этом. Я открыл процесс на python и хочу прочитать его вывод, даже если процесс еще не завершился. Процесс не завершается обычно не менее 1 минуты или до отправки прерывания. Независимо от того, что я пытаюсь, я не могу заставить его прочитать результат. Я знаю команду и аргументы, что передал работу, потому что, когда я меняю ее на subprocess.call (cmd, args), она печатает все на экране. Я также проверил, что процесс работает с ps -ax. Вот пример того, что я пытаюсь (кот/Dev/случайное имеет никакого отношения к моему проекту):Невозможно прочитать стандартный вывод из работающего процесса

proc = subprocess.Popen(["cat", "/dev/random"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
print("Process started.") 

Вот что я пытался, что не удалось до сих пор:

for line in iter(p.stdout.readline, ''): 
    strLine = str(line).rstrip() 
    print(">>> " + strLine) 
    sys.stdout.flush() 

И

output, error = proc.communicate() 
print output 

И

while proc.poll() is None: 
    print("Still waiting.") 
    print(proc.stdout.readline(1)) 

Есть больше решений, которые я пробовал, которые являются вариациями этого, но не повезло. Когда функция вызова используется без изменения stdout, все правильно печатается на консоли. Что я делаю не так?

Я использую Python 2.6.

+0

Действительно ли ваш процесс отправляет свой вывод в 'stdout', а не' stderr'? Вы это проверили? –

ответ

1

Я скопировал свой код в полной функции-и-файл, добавив одно изменение (repr), чтобы избежать печати материал, который изменяет терминальные названия и такие, что дает:

import subprocess 
import sys 

def tst(): 
    proc = subprocess.Popen(["cat", "/dev/random"], 
     stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    print("Process started.") 
    for line in iter(p.stdout.readline, ''): 
     strLine = str(line).rstrip() 
     print(">>> " + repr(strLine)) 
     sys.stdout.flush 

tst() 

(ой, выглядит как мой разрез и-паста упала круглые скобки на sys.stdout.flush безвредным в этом случае, хотя)

Запуск этого сразу производит очевидную ошибку:

Process started. 
Traceback (most recent call last): 
    File "foo.py", line 13, in <module> 
    tst() 
    File "foo.py", line 8, in tst 
    for line in iter(p.stdout.readline, ''): 
NameError: global name 'p' is not defined 

F ixing that (заменяя p на proc), пример работает для некоторого определения «works»:/dev/random не прекращает выдавать выходные данные, поэтому он работает вечно.

Средний пример будет проблемой, так как proc.communicate() будет читать весь вывод процесса, который бесконечен и, следовательно, выведет вас из памяти (в конце концов). :-)

Третий пример отлично работает.

Если вы замените cat /dev/random на что-то еще, вы можете обнаружить более интересный и, возможно, раздражающий аспект конвейеров Unix/Linux: поток stdout процесса обычно буферизируется в том случае, если он идет только на «интерактивное устройство» (как оконечное окно). Труба не является «интерактивным устройством», поэтому stdout блокируется блоком, если только эта команда не переопределяет это. Это может быть корень проблемы, которую я не могу воспроизвести здесь.

Вы можете обойти это, используя псевдо-ttys вместо (или в дополнение к) модуляPython.

+0

Спасибо, кошка работала, но мой инструмент все еще висел. Я использовал предложение в вашем ответе о pty и нашел ссылку, которая помогла: [link] (http://stackoverflow.com/questions/12419198/python-subprocess-readlines-hangs). Принимая ваш ответ, спасибо. – OldFart

Смежные вопросы