Использование Python для запуска исполняемого файла и ввода пользовательского ввода

Я пытаюсь использовать Python для автоматизации процесса, который включает в себя вызов исполняемого файла Fortran и отправку некоторых пользовательских данных. Я провел несколько часов, читая похожие вопросы и пробуя разные вещи, но мне не повезло. Вот минимальный пример, чтобы показать, что я пытался в последний раз

#!/usr/bin/python

import subprocess

# Calling executable 
ps = subprocess.Popen('fortranExecutable',shell=True,stdin=subprocess.PIPE)
ps.communicate('argument 1')
ps.communicate('argument 2')

Тем не менее, когда я пытаюсь запустить это, я получаю следующую ошибку:

  File "gridGen.py", line 216, in <module>
    ps.communicate(outputName)
  File "/opt/apps/python/epd/7.2.2/lib/python2.7/subprocess.py", line 737, in communicate
    self.stdin.write(input)
ValueError: I/O operation on closed file

Любые предложения или указатели с благодарностью.

РЕДАКТИРОВАТЬ:

Когда я вызываю исполняемый файл Fortran, он запрашивает ввод пользователя следующим образом:

fortranExecutable
Enter name of input file: 'this is where I want to put argument 1'
Enter name of output file: 'this is where I want to put argument 2'

Каким-то образом мне нужно запустить исполняемый файл, подождать, пока он запросит ввод пользователя, а затем предоставить этот ввод.

4 ответа

Решение

Если ввод не зависит от предыдущих ответов, вы можете передать их все сразу, используя .communicate():

import os
from subprocess import Popen, PIPE

p = Popen('fortranExecutable', stdin=PIPE) #NOTE: no shell=True here
p.communicate(os.linesep.join(["input 1", "input 2"]))

.communicate() ожидает завершения процесса, поэтому вы можете вызвать его не более одного раза.

Как сказано в спецификацииcommunicate()ожидает завершения подпроцесса, поэтому второй вызов будет адресован завершенному процессу.

Если вы хотите взаимодействовать с процессом, используйтеp.stdin&Co вместо этого (обратите внимание на предупреждение о тупике).

К тому времени, когда вы достигнете ps.communicate("аргумент 2"), процесс ps уже закрыт, так как ps.communicate("аргумент 1") ожидает EOF. Я думаю, что если вы хотите писать несколько раз в stdin, вам, возможно, придется использовать:

ps.stdin.write('argument 1')
ps.stdin.write('argument 2')

Ваши аргументы не должны передаваться для общения. они должны быть указаны в обращении к Popen, например: http://docs.python.org/2/library/subprocess.html

>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!
Другие вопросы по тегам