I want to run a pw.x in bash with this command: mpirun -np 4 pw.x < input.in through a python script. I used this:
from subprocess import Popen, PIPE
process = Popen( "mpirun -np 4 pw.x", shell=False, universal_newlines=True,
stdin=PIPE, stdout=PIPE, stderr=PIPE )
output, error = process.communicate();
print (output);
but it gives me this error:
Original exception was:
Traceback (most recent call last):
File "test.py", line 6, in <module>
stdin=PIPE, stdout=PIPE, stderr=PIPE )
File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'mpirun -np 4 pw.x': 'mpirun -np 4 pw.x'
How can I use "mpirun -np ..." in python scripts?
3 Answers 3
When you have shell=False in the Popen constructor, it expects the cmd to be a sequence; any type of str could be one but then the string is treated as the single element of the sequence -- this is happening in your case and the whole mpirun -np 4 pw.x string is being treated as the executable filename.
To solve this, you can:
Use
shell=Trueand keep everything else as-is, but beware of the security issues as this would be run directly in shell and you should not do this for any untrusted executableUse a proper sequence e.g.
listforcmdinPopen:import shlex process = Popen(shlex.split("mpirun -np 4 pw.x"), shell=False, ...)
Both assuming mpirun exists in your PATH.
Comments
How about changing
shell=False
to
shell=True
Comments
With shell=False, you need to parse the command line into a list yourself.
Also, unless subprocess.run() is unsuitable for your needs, you should probably avoid calling subprocess.Popen() directly.
inp = open('input.in')
process = subprocess.run(['mpirun', '-np', '4', 'pw.x'],
# Notice also the stdin= argument
stdin=inp, stdout=PIPE, stderr=PIPE,
shell=False, universal_newlines=True)
inp.close()
print(process.stdout)
If you are stuck on an older Python version, maybe try subprocess.check_output()
2 Comments
shell=True
Popen