簡介#
如果想要在 Python 中執行 shell 指令,有兩種常見的方法可以使用,其中一種是 os.system()
,另一種則是 subprocess.run()
。
os.system()#
import os
os.system('echo hello world')
os.system
會把傳入的參數作為 shell 指令,並將執行結果輸出到 stdout,最後回傳該指令執行後的回傳值 (0 代表成功,非 0 代表發生錯誤)。
因為 os.system
安全性較差,可能會產生 shell injection 的問題,已經開始逐漸被 subprocess
給取代。
subprocess.run()#
相較 os.system
,subprocess.run
除了擁有較高的安全性,它還有很高的靈活性,可以擷取指令的輸出,讓 Python 可以再對其進行額外的處裡。
subprocess.run
在呼叫上與 os.system
有點不一樣,os.system
可以直接將指令與參數透過 string 傳入,但 subprocess.run
在呼叫時,必須要把指令與參數以空格做區分,轉換成 list 來傳入。例如 ls -l
,需要改成 ['ls', '-l']
。
在執行完 shell 指令後,subprocess.run
會回傳一個 CompletedProcess 物件,其中包含了執行的指令、輸出以及回傳值。
import subprocess
res = subprocess.run(["echo", "hello world!"], capture_output=True)
print(res.returncode) # 0
print(res.stdout.decode()) # hello world!
subprocess.CompletedProcess 物件¶#
args#
執行 process 的參數,可以是 string 或是 list。
returncode#
child process 執行結束的回傳值 (一般來說 0 代表成功,非 0 代表發生錯誤)。
stdout#
child process 的 stdout。
必須在 subprocess.run()
傳入 capture_output=True
,否則 stdout 的值會是 None
資料型態是一個 bytes sequence,如果 subprocess.run()
傳入了參數 encoding
、 errors
或是 text
= True,則資料型態會是 string。
stderr#
child process 的 stderr。
必須在 subprocess.run()
傳入 capture_output=True
,否則 stderr 的值會是 None
資料型態是一個 bytes sequence,如果 subprocess.run()
傳入了參數 encoding
、 errors
或是 text
= True,則資料型態會是 string。
check_returncode()#
如果 returncode 為非 0,則會拋出例外 CalledProcessError
。