被调用的程序需要在多行中提供参数,例如
some_program par0_1 par0_2 << EOF > out.log
par1_1 par1_2 par1_3 par1_4
par2_1 par2_2
par3_1 par3_2 par3_3
par4_1
quit
EOF
到目前为止,我只在shell=True
上获得过成功(subprocess.Popen(),subprocess.call(),os.system()等都可以)。我要做的是编写一个“参数”文件并将其组织到
'cmd <参数>>日志2>&1'
,然后让Shell对其进行解释。例如:
import subprocess
cmd = 'some_program'
settings = 'par0_1 par0_2'
cmd += settings
arg = ['par1_1 par1_2 par1_3 par1_4',
'par2_1 par2_2',
'par3_1 par3_2 par3_3',
'par4_1',
'quit']
with open('parameters', 'wt') as f:
f.write('\n'.join(arg))
cmd += ' < parameters >> out.log 2>&1'
subprocess.call('cmd', shell=True)
但是我真的很想知道如何使用shell=False
来做到这一点。尝试了很多事情,但是只要我将事情整理到一个列表中,就会出现问题。使用subprocess.communicate()
提供与stdin
类似的参数可能会起作用(尽管会显得很笨拙)。但是,如果有人有一个更简单,更优雅的解决方案,我真的很感激-用Fortran编写的许多程序都要求这样的参数,我希望人们已经有了一个shell=False
解决方案。
答案 0 :(得分:0)
您当前在shell中使用的构造称为Here Document,它只是导致bem在 stdin 上将数据馈送到进程。
可以使用subprocess.Popen.communicate
通过以下方式轻松复制它:
from subprocess import Popen, PIPE, STDOUT
# here is the command and arguments, along with data for stdin
cmd = ['some_program', 'arg_0', 'arg_1']
lines = ['par1_1 par1_2 par1_3 par1_4',
'par2_1 par2_2',
'par3_1 par3_2 par3_3',
'par4_1',
'quit']
# create the process - in this example redirect stderr to stdout
process = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
# feed it the lines on stdin and get back the contents of stdout and stderr
stdout, stderr = process.communicate('\n'.join(lines))
print stdout
例如:
>>> process = Popen(["cat"], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
>>> stdout, stderr = process.communicate('\n'.join(['hello there', 'VXtal']))
>>> print stdout
hello there
VXtal