python popen.communicate () с несколькими записями стандартного ввода - PullRequest
3 голосов
/ 13 декабря 2011

У меня есть внешний процесс, который я пытаюсь запустить из Python, а затем отправить информацию через Popen.stdin.communicate (). Процесс, о котором я говорю, записывает несколько строк в stdout, затем предлагает пользователю ввести данные через stdin (число), затем записывает несколько строк или запрашивает второй ввод через stdin. Я хочу заменить ручной ввод скриптом Python, который автоматизирует это для меня. На данный момент у меня есть следующий код, который хорошо выполняет отправку первого раунда пользовательского ввода:

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
working_file.communicate(input=b'3')[0]

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

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
working_file.stdin.write(b'3')
working_file.stdin.write(b'7')

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

Может ли кто-нибудь пролить свет на то, как работает объект comunicate и как я могу сделать нечто похожее, но с несколькими записями. Также кто-нибудь знает, где хорошее место для чтения потоков и буферов?

Большое спасибо

джон

1 Ответ

0 голосов
/ 13 декабря 2011

В соответствии с документацией Python :

Обратите внимание, что если вы хотите отправить данные в стандартный поток процесса, вам нужно создать объект Popen с stdin = PIPE.Точно так же, чтобы получить что-либо кроме None в кортеже результата, вам нужно также указать stdout = PIPE и / или stderr = PIPE.

...