TAGS :Viewed: 14 - Published at: a few seconds ago

[ Python string as file argument to subprocess ]

I am trying to pass a file to a program (MolPro) that I start as subprocess with Python.

It most commonly takes a file as argument, like this in console:

path/molpro filename.ext

Where filename.ex contains the code to execute. Alternatively a bash script (what I'm trying to do but in Python):

#!/usr/bin/env bash
path/molpro << EOF
    # MolPro code
EOF

I'm trying to do the above in Python. I have tried this:

from subprocess import Popen, STDOUT, PIPE
DEVNULL = open('/dev/null', 'w')  # I'm using Python 2 so I can't use subprocess.DEVNULL
StdinCommand = '''
    MolPro code
'''

# Method 1 (stdout will be a file)
Popen(['path/molpro', StdinCommand], shell = False, stdout = None, stderr = STDOUT, stdin = DEVNULL)
# ERROR: more than 1 input file not allowed

# Method 2
p = Popen(['path/molpro', StdinCommand], shell = False, stdout = None, stderr = STDOUT, stdin = PIPE)
p.communicate(input = StdinCommand)
# ERROR: more than 1 input file not allowed

So I am pretty sure the input doesn't look enough like a file, but even looking at Python - How do I pass a string into subprocess.Popen (using the stdin argument)? I can't find what Im doing wrong.

I prefer not to:

  • Write the string to an actual file
  • set shell to True
  • (And I can't change MolPro code)

Thanks a lot for any help!

Update: if anyone is trying to do the same thing, if you don't want to wait for the job to finish (as it doesn't return anything, either way), use p.stdin.write(StdinCommand) instead.

Answer 1


It seems like your second method should work if you remove StdinCommand from the Popen() arguments:

p = Popen(['/vol/thchem/x86_64-linux/bin/molpro'], shell = False, stdout = None, stderr = STDOUT, stdin = PIPE)
p.communicate(input = StdinCommand)