HOWTO · Python
如何在 Python 中執行 Bash 命令
本教程演示如何在 Python 中執行 bash 命令,重點介紹 Git 命令。學習最佳方法,包括 subprocess 和 os.system,以有效地執行命令。透過實用的範例和清晰的解釋改進你的工作流程。非常適合希望自動化任務並簡化流程的開發人員。
本頁內容
Python 可以啟動命令列程式和 shell 命令,用於建立目錄或使用 Git 等任務。對於會結束的命令,subprocess.run() 通常是最佳起點:它可以擷取輸出和錯誤,並提供回傳碼。對於不需要擷取輸出的簡單情況,使用 os.system();當你需要在程序執行期間與它互動時,選擇 subprocess.Popen()。
用 subprocess.run() 執行命令
傳入一個引數序列,直接呼叫可執行檔。這樣可以避免讓 shell 解析命令。範例使用正在執行的 Python 直譯器,因此不依賴 Git 是否已安裝,也不依賴特定的 shell。
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-c", "print('Hello from Python')"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print("stdout:", result.stdout)
print("stderr:", result.stderr)
print("return code:", result.returncode)
stdout: b'Hello from Python\n'
stderr: b''
return code: 0
這裡的 stdout 和 stderr 是位元組,returncode 是整數。回傳碼 0 按慣例表示成功;非零值表示程式報告了問題。你可以自己檢查它,也可以傳入 check=True,讓 run() 在回傳碼非零時引發 CalledProcessError。例如,要執行 Git,傳入 ['git', 'status'] 這樣的引數列表;它的輸出取決於儲存庫,應作為資料處理,不要假定它有固定內容。
呼叫程式並不自動等於 Bash 命令。管道、重導向或 && 等 shell 語法需要 shell。設定 shell=True 是讓 Python 使用平台 shell;它並不保證是 Bash。避免把不可信的輸入插值到 shell 命令中,因為這可能導致命令注入。
用 os.system() 執行 shell 命令
os.system() 是針對簡單命令的一個受限選項,適用於你不需要擷取其輸出或詳細處理錯誤時。例如,os.system("mkdir reports") 讓平台 shell 執行建立目錄的命令。命令會寫入繼承的控制台流。該函式回傳的是狀態值,而不是命令的普通輸出;對該狀態的解釋可能因平台而異。當你需要一致地檢查擷取的輸出、錯誤或回傳碼時,優先使用 subprocess.run()。
對進行中的程序使用 subprocess.Popen()
當程式在結束前需要輸入或其他互動時,使用 subprocess.Popen()。它啟動程序,並給你的程式碼提供一個可操作的程序物件。對於輸出有界的程序,設定 stdout=subprocess.PIPE 和 stderr=subprocess.PIPE,然後呼叫 communicate() 讀取這些流並等待完成。回傳的流值是位元組,除非你另行安排解碼。
communicate() 適用於程序會結束且其擷取的輸出可以放進記憶體的情況。它不是用於無界輸出的串流方法。communicate() 完成後,程序已經結束;無需再對它呼叫 kill() 或 terminate()。對於只是會結束的普通命令,run() 提供了更簡單的介面。
選擇正確的方法
大多數命令使用 subprocess.run():傳入引數列表,在需要時擷取流,並檢查 returncode。僅當簡短的 shell 命令就足夠且其輸出和詳細狀態不重要時,才使用 os.system()。當你的程式必須管理正在執行的程序或與它交換資料時,使用 Popen()。僅當命令需要 shell 語法時才選擇 shell,並讓不可信的值遠離被插值的 shell 字串。