【问题标题】:subprocess.Popen shell=True to shell=Falsesubprocess.Popen shell=True to shell=False
【发布时间】:2017-05-19 03:58:49
【问题描述】:

我知道对子进程使用 shell=True 是不好的做法。但是对于这行代码,我不确定如何使用 shell=False 执行它

subprocess.Popen('candump -tA can0 can1 >> %s' %(file_name), shell=True)

我要运行的命令在哪里:

candump -tA can0 can1 >> file_name

file_name/path/to/file.log

【问题讨论】:

  • 顺便说一句:注意'%s' % (filename)'%s' % filename 完全相同。 ()创建一个元组,, 可以!因此,如果您想创建一个 1 元素元组,请执行 (filename, )

标签: python shell subprocess


【解决方案1】:

只有 shell 模式支持内联管道运算符,因此您需要手动进行重定向。此外,您需要将命令行拆分为单独的参数,您可以手动执行这些参数,也可以让 shlex 模块为您执行:

subprocess.Popen(shlex.split('candump -tA can0 can1'), stdout=open(file_name, 'ab'))

【讨论】:

  • 你为什么建议shlex.split(),而不是明确的argv数组/列表?
  • @CharlesDuffy 使用 shlex 使其最接近问题的原始表述。手动拆分还是不错的。我把答案澄清了一点。
  • 点头。我认为列表方法与"explicit is better than implicit" 保持一致,但在风格问题上意见肯定会有所不同。
  • ...OTOH,我认为有一个非常有力的论据,即显式列表方法会导致更少的错误:使用shlex.split('candump -o %s' % file) 的人容易出现问题(即文件名包含空格)使用['candump', '-o', file] 的人不是。
  • @CharlesDuffy 是的,这是一个很好的观点。 Shlex 不应与未清理/未转义的输入一起使用。我通常只将它与文字/非构造命令一起使用,因为在中间没有逗号和引号的情况下更容易看到命令行(特别是如果命令行包含引号和/或逗号)。
【解决方案2】:

你不能像shell=True那样直接在命令中使用管道,但是很容易适应:

with open(file_name, 'ab') as outf:
    proc = subprocess.Popen(['candump', '-tA', 'can0', 'can1'], stdout=outf)

这会在 Python 级别打开文件以进行二进制追加,并将其作为 stdout 传递给子进程。

【讨论】:

  • 与 open() 一起使用时,'ab' 代表什么?
  • @avelampudi append binary.
猜你喜欢
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多