Взаимодействие с подпроцессами Python, почему мой процесс работает с Popen.communicate, но не с Popen.stdout.read ()? - PullRequest
6 голосов
/ 13 марта 2012

Я пытаюсь связаться с ботом чата из командной строки с 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, но когда я запускаю чат-бота, ничего не происходит. Итак, мой вопрос: Как это отличается в захвате вывода от использования Popen.communicate ()?

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

Ответы [ 2 ]

9 голосов
/ 13 марта 2012

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

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

3 голосов
/ 16 марта 2012

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

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

...