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命令中的元字符