使用python中的命令行参数避免shell = True

时间:2017-04-18 13:28:32

标签: python shell

我想在test.py脚本中运行一个带有几个参数的shell命令行。 test.py以:

运行
python test.py filename file_2 int

test.py看起来类似于:

import sys

filename = sys.argv[1]
file_2 = sys.argv[2]
num = sys.argv[3]

subprocess.call("xargs /bin/bash  build/install/programme/bin/programme option -n "+num+" --csv-file="+str(filename)+" -c files/"+str(file_2)+ "< /tmp/my_ids_"+str(file_2)+"_"+str(num),shell=True)

关键是我想避免使用shell = True ,但到目前为止我找到的所有选项都没有为我在命令行中添加的参数提供一个很好的解决方案。

到目前为止,我已尝试通过将其与Popen分开来尝试不同的选项,例如:

import sys

filename = sys.argv[1]
file_2 = sys.argv[2]
num = sys.argv[3]

subprocess.Popen(["xargs","/bin/bash","build/install/programme/bin/programme","option","-n", str(num),"--csv-file=",str(filename),"-c","files/",str(file_2),"<",str("/tmp/my_ids_"+str(file_2)+"_"+str(num))])

但我没有取得任何成绩。还尝试了shlex,但在文档中我没有看到任何能够在命令中添加参数的选项。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

您的原始代码等同于运行以下bash命令:

xargs \
  /bin/bash \
  build/install/programme/bin/programme \
  option \
  -n            "$int" \
  "--csv-file=" "$filename" \
  -c            "files/"           "${file_2}" \
  '<'           "/tmp/my_ids_${file_2}_${int}"

由于所有相同的原因,这也不会有效。

import sys

filename = sys.argv[1]
file_2 = sys.argv[2]
num = int(sys.argv[3])

subprocess.Popen([
  "xargs",
  "/bin/bash",
  "build/install/programme/bin/programme",
  "option",
  "-n", str(num),
  "--csv-file=%s" % filename,
  "-c", "files/%s" % file_2,
], stdin=open("/tmp/my_ids_%s_%s" % (file_2, num), 'r')

请注意差异:

  • 单个参数始终作为单个列表成员传递。这意味着--csv-file=filename是一回事,并且前缀files/和变量file_2中包含的字符串需要在同一个列表元素中传递。
  • 重定向(<)是到shell 的说明,而不是程序的参数。因此,您无法在此处使用它们,但应使用其他选项(例如stdin的{​​{1}}和stdout参数)来模拟它们的效果。
  • Popen是整数类型的名称;使用变量名称int可保留原始名称。