Используйте подпроцесс, чтобы открыть исполняемый файл и взаимодействовать с ним - PullRequest
1 голос
/ 11 февраля 2020

Я использую Python для сценария запуска исполняемой программы. Если мы откроем exe-программу в оболочке, мы могли бы ввести в программу разные команды, такие как «a», «b», «c». Эти команды нельзя передавать как флаги в программу exe. Я хочу использовать Python для многократного запуска сценария запуска этой exe-программы с пользовательским вводом exe-программы, указывающим c. Но если я запускаю "program.exe" с

p = subprocess.call(['program.exe'],
                     stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE,
                     )

Python, он не прекратится. Можно ли достичь этой цели с помощью подпроцесса в Python?

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Осторожно: subprocess.call не вернется до завершения дочернего процесса. Таким образом, у вас нет возможности записать что-либо на стандартный ввод дочернего элемента.

Если вы можете подготовить кучу команд заранее и если выходные данные не рискуют заполнить системный буфер, вы все равно можете использовать call таким образом:

cmds = "a\nb\nc\n"

p = subprocess.call(['program.exe'],
                     stdin=io.StringIO(cmds),
                     stdout=subprocess.PIPE,
                     )

Но более надежный способ заключается в непосредственном использовании конструктора Popen и последующем вводе:

p = subprocess.Popen(['program.exe'],
                 stdin=subprocess.PIPE,
                 stdout=subprocess.PIPE,
                 )
p.stdin.write("a\n");
p.stdin.write("b\n");
...
p.stdin.close();
p.wait();

Если вы знаете, что одна подкоманда будет генерировать очень большие Вывод вы можете прочитать перед отправкой следующего. Остерегайтесь блокировки, ожидая ввода, который ребенок еще не отправил ...

2 голосов
/ 11 февраля 2020

Во-первых, вы должны использовать p = subprocess.Popen(…), чтобы получить объект подпроцесса. subprocess.call(…) даст вам только статус возврата, и этого недостаточно.

Если p является вашим объектом соединения, вы можете отправить свои команды на p.stdin, например p.stdin.write("a\n"), и затем прочитать out p.stdout() до следующего указания, что вывод команды завершен. То, как вы обнаружите это, зависит от указанной программы.

Затем вы можете отправить следующую команду и прочитать ее вывод.

В конце вы можете сделать p.stdin.close(), чтобы подать сигнал EOF ot. другой процесс, а затем он должен завершиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...