在python脚本中使用mpirun -np

问题描述 投票:0回答:3

我想用这个命令在bash中运行一个pw.x:mpirun -np 4 pw.x <input.in通过python脚本。我用过这个:

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);

但它给了我这个错误:

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'

如何在python脚本中使用“mpirun -np ...”?

python bash command-line mpi
3个回答
1
投票

当你在shell=False构造函数中有Popen时,它期望cmd是一个序列;任何类型的str都可以是一个但是然后字符串被视为序列的单个元素 - 这在你的情况下发生,并且整个mpirun -np 4 pw.x字符串被视为可执行文件名。

要解决此问题,您可以:

  • 使用shell=True并按原样保留其他所有内容,但请注意安全问题,因为这将直接在shell中运行,您不应该为任何不受信任的可执行文件执行此操作
  • 使用正确的顺序,例如listcmdPopenimport shlex process = Popen(shlex.split("mpirun -np 4 pw.x"), shell=False, ...)

假设mpirun存在于你的PATH中。


0
投票

如何改变

shell=False

shell=True

0
投票

使用shell=False,您需要自己将命令行解析为列表。

此外,除非subprocess.run()不适合您的需求,否则您应该避免直接调用subprocess.Popen()

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)

如果您遇到旧的Python版本,可以尝试subprocess.check_output()

© www.soinside.com 2019 - 2024. All rights reserved.