Чтение в режиме реального времени из subprocess.stdout в Windows

Чтобы подчеркнуть, проблема заключается в чтении в режиме реального времени вместо неблокирующего чтения . Он был задан раньше, например subprocess.Popen.stdout – чтение stdout в режиме реального времени (снова) . Но удовлетворительное решение не было предложено.

Например, следующий код пытается имитировать оболочку python.

  • Есть ли способ найти размер буфера файлового объекта
  • В чем разница между аргументом буферизации open () и жестко запрограммированным размером буфера для чтения, используемым при итерации через файл?
  • import subprocess p = subprocess.Popen(['python'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) while True: line = input('>>> ') p.stdin.write(line.encode()) print('>>> ', p.stdout.read().decode()) 

    Однако он будет заблокирован при чтении с p.stdout . После обыска я обнаружил следующие два возможных суждения.

    1. используя fctrl и O_NONBLOCK
    2. использование thread и queue

    В то время как 1-й soution может работать и работать только с linux, второй soution просто превращает блокировку чтения в неблокируемое чтение, то есть я не могу получить вывод в реальном времени подпроцесса. Например, если я нахожу « print("hello") , я ничего не получаю от p.stdout используя второе решение.

    Возможно, кто-то предложит p.communite . К сожалению, он не подходит в этом случае, так как он закрывает stdin, как описано здесь .

    Итак, есть ли решения для Windows ?

    Отредактировано: даже если -u включен, а p.stdout.read заменен на p.stdout.readline , проблема все еще существует.

     import subprocess p = subprocess.Popen(['python', '-u'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) while True: line = input('>>> ') p.stdin.write(line.encode()) p.stdin.flush() print('>>> ', p.stdout.readline().decode()) 

    Решение. Ниже приведен окончательный код, основанный на ответе и комментариях Дж. Ф. Себастьяна.

     from subprocess import Popen, PIPE, STDOUT with Popen( ['python', '-i', '-q'], stdin=PIPE, stdout=PIPE, stderr=STDOUT, bufsize=0 ) as process: while True: line = input('>>> ') if not line: break process.stdin.write((line+'\n').encode()) print(process.stdout.readline().decode(), end='') 

    Следует отметить, что программа зависает, когда команда не запускает вывод.

  • что именно делает файл python file.flush ()?
  • Emacs / Python: запуск оболочки python в режиме буферизации в буферном режиме и блочном буферизации
  • В чем разница между аргументом буферизации open () и жестко запрограммированным размером буфера для чтения, используемым при итерации через файл?
  • Есть ли способ найти размер буфера файлового объекта
  • One Solution collect form web for “Чтение в режиме реального времени из subprocess.stdout в Windows”

    Вот полный рабочий пример, который использует подпроцесс в интерактивном режиме:

     #!/usr/bin/env python3 import sys from subprocess import Popen, PIPE, DEVNULL with Popen([sys.executable, '-i'], stdin=PIPE, stdout=PIPE, stderr=DEVNULL, universal_newlines=True) as process: for i in range(10): print("{}**2".format(i), file=process.stdin, flush=True) square = process.stdout.readline() print(square, end='') 

    Вот еще один пример: как запустить [sys.executable, '-u', 'test.py'] интерактивном режиме .

    Python - лучший язык программирования в мире.