Использование 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!