subprocess中命令为参数序列和字符串的区别
参数args
参数args
可以是一个参数序列,也可以是一个单独的字符串。参数序列通常是首选的,因为它允许模块处理参数的转义和引号(例如,允许文件名中有空格)。
如果传递参数序列,默认情况下,程序执行序列的第一个元素,后面所有的元素都作为参数。
如果传一个单独字符串,要么参数shell
为True,要么字符串必须没有指定任何参数的可执行程序的名称。
所以,一般的搭配是参数序列和shell=False
,字符串和shell=True
。
参数shell
shell参数设置是否在单独的shell中执行命令。如果shell=True
,则是派生一个新的shell来解释执行命令。如果你使用Python主要是为了增强它在大多数系统shell上提供的控制流,并且还想方便的访问shell特性,如shell的管道符、文件通配符、环境变量扩展或者~扩展到home目录等,这个参数将非常有用。
不同平台下shell参数使用
shell=False
对于Unix平台,如果args
是字符串,这个字符串将被解释为程序的名称或路径,然后被执行。然而,这仅仅只有在不给这个程序传递任何参数时才能被执行。
import subprocess
subprocess.Popen('ls', shell=False) # get the result
subprocess.Popen('ls', shell=False) # raise Exception: FileNotFoundError
对于windows平台,如果args
是个序列,它将被转换成一个字符串通过以下方式:Converting an argument swquence to a string on Windows ,这是因为底层的CreateProcess()
只能操作字符串。
shell=True
在Unix平台下shell=True
,shell默认为/bin/sh
。如果args
是字符串,通过shell执行字符串指定的命令。这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。例如, 使用引号或反斜杠转义包含空格的文件名。如果args
是一个序列,第一个元素指定了命令字符串,其它的元素他的参数。
在Windows平台下shell=True
,环境变量COMSPEC
指定了默认的shell。只有当你想要执行的命令内置于shell中时,你才需要指定shell=True
(例如dir
或copy
)。运行批处理文件或基于控制台的可执行文件不需要shell=True
。
args的参数序列和字符串的区别
这里的字符串指的是
shell=True
下的字符串
- 使用序列不需要派生一个新的shell解释器。所以比字符串更快一点
- 使用shell参数容易引起shell注入漏洞,使用shlex.quote() 函数可以正确转义空格和shell命令中的元字符