2014-02-03 4 views
4

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

#!/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 

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

EDIT:

Когда я называю 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' 

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

ответ

5

Если вход не зависит от предыдущих ответов, то вы можете передать их все сразу, используя .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() ждет завершения процесса, поэтому вы можете назвать его не более одного раза.

+0

Это работает отлично. Спасибо! – James

1

Поскольку spec sayscommunicate() ожидает завершения подпроцесса, то второй вызов будет адресован законченному процессу.

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

0

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

>>> 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! 
+0

Проблема в том, что исполняемый файл запускается, а затем запрашивает ввод пользователя. Мне нужно подождать, пока пользовательский ввод не будет запрошен, а затем заполните этот вход. Всего три входа. – James

0

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

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

Я пробовал это, но все же получил ошибку. См. Выше edit для уточнения проблемы. – James

Смежные вопросы