如何组织应该在多行上的cmd参数?

时间:2018-11-26 04:06:58

标签: python subprocess

被调用的程序需要在多行中提供参数,例如

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解决方案。

1 个答案:

答案 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