子流程如何处理列表和shell = True

时间:2018-12-06 22:02:30

标签: python subprocess

我喜欢shell=False来避免shell=True带来的各种问题。有时我看到这样的代码,它返回True,但似乎没有打印任何内容,我也不知道发生了什么。

subprocess.run(['echo', 'hi'], shell=True, check=True).returncode == 0

通过对比,

subprocess.run(['echo', 'hi'], shell=False, check=True).returncode == 0

实际上会打印到标准输出。

当我将列表作为参数和shell = True传递时会发生什么?

1 个答案:

答案 0 :(得分:2)

来自the documentation

  

在shell = True的POSIX上,shell默认为/ bin / sh。如果args是字符串,则该字符串指定要通过外壳执行的命令。这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。例如,这包括在文件名中使用引号或反斜杠转义。 如果args是序列,则第一项指定命令字符串,任何其他项都将被视为shell本身的其他参数。

因此,您的命令等效于sh -c "echo" "hi",该命令只执行echo而没有参数。

一个更有用的示例是使用此机制将任意数据安全地传递到shell代码段:

file1='my file.txt'
file2='Author&Title - [FOO] **proper**.mp3'
subprocess.run(
    ['for f; do printf "Input: %s\n" "$f"; done', '_',
      file1, file2],
    shell=True, check=True)

这会从shell中打印出变量,而不必担心转义shell元字符。 (多余的'_'变成$0)。