Using Python to run executable and fill in user input

James picture James · Feb 3, 2014 · Viewed 16.1k times · Source

I'm trying to use Python to automate a process that involves calling a Fortran executable and submitting some user inputs. I've spent a few hours reading through similar questions and trying different things, but haven't had any luck. Here is a minimal example to show what I tried last

#!/usr/bin/python

import subprocess

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

However, when I try to run this, I get the following error:

  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

Any suggestions or pointers are greatly appreciated.

EDIT:

When I call the Fortran executable, it asks for user input as follows:

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'

Somehow, I need to run the executable, wait until it asks for user input and then supply that input.

Answer

jfs picture jfs · Mar 8, 2014

If the input doesn't depend on the previous answers then you could pass them all at once using .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() waits for process to terminate therefore you may call it at most once.