Есть ли метод для чтения символов из экземпляра subprocess.Popen, когда вызываемый им процесс еще не выпустил символ новой строки? - PullRequest
3 голосов
/ 25 марта 2011

Я пытаюсь обернуть программу, которая обычно используется на работе. При вызове с недостаточным количеством аргументов или с ошибочным аргументом программа выдает приглашение пользователю, запрашивая необходимый ввод. Как следствие, при вызове подпрограммы с subprocess.Popen, подпрограмма никогда не отправляет какую-либо информацию в stdout или stderr, когда передаются неправильные параметры subprocess.Popen.communicate () и subprocess.Popen.read (1) оба ждут символа новой строки, прежде чем какая-либо информация станет доступной.

Есть ли способ извлечь информацию из subprocess.Popen.stdout до появления символа новой строки? Если нет, существует ли какой-либо метод, который можно использовать для определения того, ожидает ли подпроцесс ввода?

Ответы [ 2 ]

2 голосов
/ 25 марта 2011

Спросив немного, кто-то указал мне на решение.Используйте pexpect.spawn и pexpect.expect.Например:

Bash "скрипт" в файле с именем prompt.sh для эмуляции проблемы - чтение не может быть вызвано напрямую из pexpect.spawn.#! / bin / bash

read -p "This is a prompt: "

Это будет зависать при вызове subprocess.Popen.Это может быть обработано pexpect.spawn, однако:

import pexpect
child = pexpect.spawn('./prompt.sh')
child.expect(search)
>>> 0
print child.after #Prints the matched text
>>> 'This is a prompt: '

Список, скомпилированное регулярное выражение или список скомпилированного регулярного выражения также может использоваться вместо строки в pexpect.expect для обработки различных запросов.

2 голосов
/ 25 марта 2011

Первое, что нужно попробовать: используйте аргумент bufsize для Popen и установите для него 0:

subprocess.Popen(args, bufsize=0, ...)

К сожалению, будет ли это работать, также зависит от того, как подпроцесс сбрасывает свой вывод, и я полагаю, что вы не контролируете это.

На некоторых платформах, когда данные, записанные в stdout, сбрасываются, на самом деле изменяется в зависимости от того, обнаруживает ли базовая библиотека ввода / вывода интерактивный терминал или канал. Поэтому, хотя вы можете подумать, что данные там ожидают чтения - потому что именно так они работают в окне терминала - они могут быть буферизованы строкой, когда вы запускаете ту же программу, что и подпроцесс из другого в Python.

Добавлено: Я только что понял, что в любом случае bufsize=0 по умолчанию. Гайки.

...