Подпроцесс Python, почему мой процесс работает с Popen.communicate, но не Popen.stdout.read()?

Я пытаюсь общаться с ботом командной строки с Python с помощью модуля subprocess. (http://howie.sourceforge.net/, используя скомпилированный двоичный код win32, у меня есть причины!)

Это работает:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
output = proc.communicate()

Но Popen.communicate ждет завершения процесса (и отправляет его EOF?), я хочу иметь возможность взаимодействовать с ним. Очевидным решением для этого было читать stdout/write stdin следующим образом:

Это не работает:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
while True: print proc.stdout.readline()

(Обратите внимание, что я использую более сложный код на основе http://code.activestate.com/recipes/440554/, но проблема такая же.)

Проблема в том, что второй подход отлично работает для связи с cmd, но когда я запускаю chatbot, ничего. Итак, мой вопрос: как это отличается от захвата вывода на использование Popen.communicate()?

то есть. Я могу использовать второй подход для использования командной строки в соответствии с нормальным, пока я не запустил chatbot, после чего я перестаю получать выходные данные. Использование первого подхода правильно отображает первые несколько строк вывода от бота, но не позволяет мне взаимодействовать с ним.

Одно из основных различий между ними заключается в том, что связь() закрывает stdin после отправки данных. Я не знаю о вашем конкретном случае, но во многих случаях это означает, что если процесс ожидает окончания ввода пользователем, он получит его, когда будет использоваться связь(), и никогда не получит его, когда код блокирует read() или readline().

Попробуйте сначала добавить Popen.stdin.close() и посмотреть, влияет ли это на ваш случай.

9
ответ дан 12 марта '12 в 23:45
источник

Если вы хотите взаимодействовать с программой после отправки EOF, а не с помощью Popen.stdin.close(), вы можете вручную отправить символ End Of File из командной строки, который имеет тот же эффект, но оставляет stdin открытым.

В Python эта последовательность escape символов '\x1a'.

3
ответ дан 16 марта '12 в 8:59
источник