python subprocess.check_output vs os.system问题

时间:2018-05-25 19:46:27

标签: python subprocess

所以我试图使用“更新的”#39;用于在bash shell中执行fortran程序的子进程...不确定我做错了什么,但如果我做了

result = os.system('./get_cpus -inp ./output_00076 -xc {:.4e} -yc {:.4e} -zc {:.4e} -rad {:.4e}'.format(loc[0],loc[1],loc[2],rad) )

我在结果中得到了fortran程序的输出(来自get_cpus)。认为似乎工作正常......但如果我这样做:

result = subprocess.check_output(['./get_cpus',
                                 '-inp ./output_00076',
                                 '-xc {:.4e}'.format(loc[0]),
                                 '-yc {:.4e}'.format(loc[1]),
                                 '-zc {:.4e}'.format(loc[2]),
                                 '-rad {:.4e}'.format(rad)])

我收到错误:

./get_cpus -inp ./output_00076 -xc 3.1670e-01 -yc 9.6000e-02 -zc 2.4170e-01 -rad 2.0360e-03
forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Image              PC                Routine            Line        Source             
get_cpus           0000000000409CD8  Unknown               Unknown  Unknown
get_cpus           000000000042AF2D  Unknown               Unknown  Unknown
get_cpus           0000000000429696  Unknown               Unknown  Unknown
get_cpus           00000000004065E7  get_cpus_IP_read_         280  get_cpus.f90
get_cpus           00000000004029B1  MAIN__                     46  get_cpus.f90
get_cpus           000000000040297E  Unknown               Unknown  Unknown
libc-2.22.so       00007FFFECE456D5  __libc_start_main     Unknown  Unknown
get_cpus           00000000004028A9  Unknown               Unknown  Unknown
Traceback (most recent call last):
  File "findCPUs.py", line 45, in <module>
    '-rad {:.4e}'.format(rad)])
  File "/nasa/pkgsrc/2014Q4/lib/python2.7/subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['./get_cpus', '-inp ./output_00076', '-xc 3.1670e-01', '-yc 9.6000e-02', '-zc 2.4170e-01', '-rad 2.0360e-03']' returned non-zero exit status 59

&#39; CalledProcessError:Command&#39;看起来很好......

我已经尝试过这样做,因为shell = True&#39;然后我让程序运行,但输入都丢失了,因为fortran代码返回&#39;用法&#39;声明(描述我需要输入参数)。 ????例如 -

result = subprocess.check_output(['./get_cpus',
                                 '-inp ./output_00076',
                                 '-xc {:.4e}'.format(loc[0]),
                                 '-yc {:.4e}'.format(loc[1]),
                                 '-zc {:.4e}'.format(loc[2]),
                                  '-rad {:.4e}'.format(rad)],
                                 shell=True, stdin=subprocess.PIPE)

我做错了什么?

1 个答案:

答案 0 :(得分:2)

使用os.system,您自己编写参数字符串。它可以工作,但它很丑陋,易于代码注入,如果你忘记引用它们,对于一些带空格的参数不健壮。所以subprocess是正确的选择。

现在,要求subprocess使用参数列表。

这里你的论点分裂是错误的。您将2个参数包含在一个(空格分隔)中,例如:

  '-xc {:.4e}'.format(loc[0]),

这个“论证”发布到系统,如

"-xc .4555"

(是的,带引号),这会混淆参数解析。

修复:正确分隔参数:

result = subprocess.check_output(['./get_cpus',
                                 '-inp','./output_00076',
                                 '-xc','{:.4e}'.format(loc[0]),
                                 '-yc','{:.4e}'.format(loc[1]),
                                 '-zc','{:.4e}'.format(loc[2]),
                                 '-rad','{:.4e}'.format(rad)],
                                 stdin = subprocess.PIPE)

您也不需要shell=True。除快速黑客外,它几乎从不有用。通常不解决任何问题,并且是一种安全责任(代码注入)