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