subprocess中命令為引數序列和字串的區別

yw_sun發表於2020-10-20

引數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(例如dircopy)。執行批處理檔案或基於控制檯的可執行檔案不需要shell=True

args的引數序列和字串的區別

這裡的字串指的是shell=True下的字串

  • 使用序列不需要派生一個新的shell直譯器。所以比字串更快一點
  • 使用shell引數容易引起shell注入漏洞,使用shlex.quote() 函式可以正確轉義空格和shell命令中的元字元

參考

相關文章