我喜欢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传递时会发生什么?
答案 0 :(得分:2)
在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
)。