在python脚本中使用mpirun-np

在python脚本中使用mpirun-np,python,bash,command-line,mpi,Python,Bash,Command Line,Mpi,我想在bash中使用以下命令运行pw.x:mpirun-np4 pw.x

我想在bash中使用以下命令运行pw.x:mpirun-np4 pw.x
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'
原始异常是:
回溯(最近一次呼叫最后一次):
文件“test.py”,第6行,在
标准偏差=管道,标准偏差=管道,标准偏差=管道)
文件“/usr/lib/python3.6/subprocess.py”,第709行,在__
恢复信号,启动新会话)
文件“/usr/lib/python3.6/subprocess.py”,第1344行,在执行子进程中
引发子项异常类型(错误号、错误消息、错误文件名)
FileNotFoundError:[Errno 2]没有这样的文件或目录:“mpirun-np 4 pw.x”:“mpirun-np 4 pw.x”
如何在python脚本中使用“mpirun-np…”?

如何更改

shell=False


当在
Popen
构造函数中有
shell=False
时,它希望
cmd
是一个序列;任何类型的
str
都可以是一个,但是字符串被视为序列的单个元素——这在您的案例中发生,整个
mpirun-np 4 pw.x
字符串被视为可执行文件名

要解决此问题,您可以:

  • 使用
    shell=True
    并保持所有其他内容不变,但要注意安全问题,因为这将直接在shell中运行,并且不应对任何不受信任的可执行文件执行此操作

  • Popen
    中的
    cmd
    使用适当的顺序,例如
    list

    import shlex
    process = Popen(shlex.split("mpirun -np 4 pw.x"), shell=False, ...)
    

假设
mpirun
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版本,请尝试
子流程。检查输出()

:拆分您的命令并将其作为列表传递给
Popen
,另请参阅为什么要避免
shell=True
,谢谢您的回答,但它对我不起作用,也不会在输出中显示任何内容。
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)