Получение небуферизованного вывода из подпроцесса не работает Python - PullRequest
0 голосов
/ 03 июня 2018

У меня есть основания полагать, что если я запускаю его с флагами, он запускает инструмент, который генерирует сообщения все время.Когда я пытаюсь запустить его с подпроцессом, я получаю вывод в cmd, и это нормально.Дело в том, что я хочу взять эти сообщения и что-то с ними сделать, но по какой-то причине метод небуфринга не работает, и я не получаю никакого сообщения.

Ниже приведен код, который я пробовал:

p = subprocess.Popen(
 ["my_tool.exe","runMode","y","port","1234"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT, bufsize=1)

Чтобы сгенерировать вывод, попробуйте следующее:

for line in p.stdout:
    print("CUR", line)

и:

while p.poll() is None:
    line = p.stdout.read(2)
    print("Print:" + line)

и:

for line in iter(p.stdout.readline, b''):
    print(line)
p.stdout.close()

Любая идея, почемукодовые блоки в строке stdout всегда?

ОБНОВЛЕНИЕ:

Например, если у меня есть следующая бесконечная программа:

inf.py

import time
i = 0
while True:
    time.sleep(0.5)
    print(i)
    i += 1

и следующий код, который его запускает:

p = subprocess.Popen(r"C:\Python35\python.exe inf.py",
                     stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)

и для генерации вывода я использую один из перечисленных выше методов. Если я остановлю его с помощью CTRL + C, он всегда застрянет на этой строке:

  File "C:\Python35\lib\encodings\cp1252.py", line 22, in decode
    def decode(self, input, final=False):

1 Ответ

0 голосов
/ 06 мая 2019

Сначала я установил следующую переменную окружения: PYTHONUNBUFFERED=1

Затем я немного изменил ваш код:

read_infinite.py

import subprocess

binary = "C:\\Python35\\python.exe"
script = "C:\\temp\\python\\tests\\inf.py"

p = subprocess.Popen([binary, script], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)

while p.poll() is None:
    #line = p.stdout.read(2)
    line = p.stdout.readline()
    if line:
        print("Result: %r" % line)

Удаление bufsize=1 работает так же.

Сначала я получил ошибку, что inf.py не был найден, но это не было показано, потому что распечатки read_infinite.py прокручивали ошибку.И процесс остановился после большого количества строк «Result:» (переменная «строка» пуста).

Удаление if line: и добавление time.sleep(0.5) после печати (помните import time!) Показываетрезультаты те же.

Таким образом, решение таково: родитель должен ждать ребенка.

...