【问题标题】:Issue with python subprocess.check_output vs os.systempython subprocess.check_output 与 os.system 的问题
【发布时间】:2018-05-25 19:46:26
【问题描述】:

所以我正在尝试使用“较新”的子进程在 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

“CalledProcessError:Command”对我来说看起来不错...

我已经用 'shell=True' 尝试过这个,然后我让程序运行,但是输入都丢失了,因为 fortran 代码返回了 'usage' 语句(描述我需要输入参数)。 ???例如-

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)

我做错了什么??

【问题讨论】:

  • 尝试将参数提供为一个字符串,而不是字符串列表。我遇到过一些场景,出于某种原因,它成功了。
  • 请注意,shell=True 并不意味着 bash - 来自文档:“在 shell=True 的 POSIX 上,shell 默认为 /bin/sh。

标签: python subprocess


【解决方案1】:

使用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。除了快速破解之外,它几乎从不有用。通常不能解决任何问题,并且是安全责任(代码注入)

【讨论】:

  • 谢谢...我现在就试试。我永远不会抓住它!
  • 是的——做到了。谢谢@Jean-François Fabre
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-04
  • 2014-10-09
相关资源
最近更新 更多