Python中subprocess.run()執(zhí)行命令、檢查狀態(tài)與結(jié)果處理深入理解
前言
subprocess.run()
是 Python 3 中用于執(zhí)行系統(tǒng)命令的一個重要函數(shù)。它提供了一個簡潔、強(qiáng)大且直觀的方式來運(yùn)行外部程序或系統(tǒng)命令,特別適用于那些需要和系統(tǒng)交互或者需要調(diào)用外部可執(zhí)行程序的場景。在這篇文章中,我們將詳細(xì)討論如何使用 subprocess.run()
函數(shù),特別是 check=True
的用法,以及如何處理其狀態(tài)和結(jié)果。
1. subprocess.run() 概述
subprocess.run()
是 subprocess
模塊的一部分,它是替代舊版模塊(如 os.system()
)的更強(qiáng)大且安全的方法。其主要目的是允許我們在 Python 中執(zhí)行外部命令,并捕獲輸出、錯誤信息以及返回狀態(tài)。
基本的語法如下:
import subprocess result = subprocess.run(command, check=True, ...)
在這個語法中,command
是一個字符串或列表,用于表示要執(zhí)行的系統(tǒng)命令。check=True
表示如果命令執(zhí)行失敗(即返回非零退出碼),函數(shù)將拋出一個 subprocess.CalledProcessError
異常。
2. subprocess.run() 參數(shù)詳解
command
:一個列表或字符串,表示要執(zhí)行的命令。使用列表形式更安全,因?yàn)樗梢员苊?shell 注入風(fēng)險(xiǎn)。例如['ls', '-l']
而不是'ls -l'
。check
:布爾值,默認(rèn)是False
。如果設(shè)為True
,命令返回非零退出狀態(tài)碼時(shí)會引發(fā)CalledProcessError
異常。這個參數(shù)非常有用,尤其是在處理必須執(zhí)行成功的命令時(shí),可以避免繼續(xù)執(zhí)行錯誤邏輯。stdout
:定義如何處理命令的標(biāo)準(zhǔn)輸出,例如設(shè)置為subprocess.PIPE
可以捕獲輸出。stderr
:類似于stdout
,用于處理標(biāo)準(zhǔn)錯誤輸出。text
:如果設(shè)為True
,會將輸出解碼為字符串,否則返回字節(jié)類型。capture_output
:如果設(shè)為True
,則同時(shí)捕獲標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤。
3. 一個基本例子
來看一個簡單的例子:
import subprocess try: result = subprocess.run(['ls', '-l'], check=True, text=True, capture_output=True) print("標(biāo)準(zhǔn)輸出:", result.stdout) except subprocess.CalledProcessError as e: print("命令執(zhí)行失敗,錯誤碼:", e.returncode) print("錯誤輸出:", e.stderr)
在這個例子中:
- 我們使用
['ls', '-l']
作為要執(zhí)行的命令。 check=True
表示如果命令返回非零的狀態(tài)碼,程序會拋出異常。text=True
會將輸出解碼為字符串,方便打印和處理。capture_output=True
會捕獲命令的輸出和錯誤。
4. 處理命令的執(zhí)行狀態(tài)
當(dāng)我們使用 subprocess.run()
執(zhí)行命令時(shí),可以通過以下幾種方式來處理命令的狀態(tài)和結(jié)果:
捕獲返回碼:
subprocess.CompletedProcess
對象的returncode
屬性存儲了命令執(zhí)行后的返回碼。如果返回碼為0
,則表示執(zhí)行成功;否則表示失敗。
result = subprocess.run(['ls', '-l'], text=True, capture_output=True) if result.returncode == 0: print("命令執(zhí)行成功") else: print("命令執(zhí)行失敗,返回碼:", result.returncode)
使用
check=True
處理異常:- 當(dāng)
check=True
時(shí),非零的返回碼會引發(fā)subprocess.CalledProcessError
異常,這樣我們就可以用try...except
塊來處理錯誤情況。
try: subprocess.run(['false'], check=True) except subprocess.CalledProcessError as e: print(f"命令執(zhí)行失敗,錯誤碼: {e.returncode}")
這個例子中,
false
是一個始終返回非零狀態(tài)碼的命令,因此會觸發(fā)異常處理塊。- 當(dāng)
捕獲輸出:
- 如果希望查看命令的標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)錯誤,可以使用
capture_output=True
或直接設(shè)置stdout
和stderr
參數(shù)。
result = subprocess.run(['echo', 'Hello, World!'], text=True, capture_output=True) print("標(biāo)準(zhǔn)輸出:", result.stdout)
在這里,
result.stdout
會包含命令的輸出內(nèi)容"Hello, World!\n"
。- 如果希望查看命令的標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)錯誤,可以使用
處理標(biāo)準(zhǔn)錯誤輸出:
- 類似于標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯誤輸出可以使用
result.stderr
捕獲。例如:
try: result = subprocess.run(['ls', '/nonexistent'], check=True, text=True, capture_output=True) except subprocess.CalledProcessError as e: print("錯誤輸出:", e.stderr)
在這種情況下,如果
/nonexistent
目錄不存在,錯誤信息會被捕獲并打印出來。- 類似于標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯誤輸出可以使用
5. subprocess.CompletedProcess 對象
subprocess.run()
返回一個 subprocess.CompletedProcess
對象,它包含了多個屬性:
args
:執(zhí)行的命令。returncode
:命令執(zhí)行的返回碼,0 表示成功,非零表示失敗。stdout
:標(biāo)準(zhǔn)輸出的內(nèi)容(如果設(shè)置了capture_output=True
或stdout=subprocess.PIPE
)。stderr
:標(biāo)準(zhǔn)錯誤輸出的內(nèi)容(如果設(shè)置了capture_output=True
或stderr=subprocess.PIPE
)。
一個例子來展示這些屬性:
result = subprocess.run(['echo', 'Python subprocess module!'], text=True, capture_output=True) print("命令:", result.args) print("返回碼:", result.returncode) print("標(biāo)準(zhǔn)輸出:", result.stdout)
在這個例子中,result
對象包含了所有與命令執(zhí)行相關(guān)的信息,這使得它非常靈活,適用于處理各種執(zhí)行情況。
6. 結(jié)論
subprocess.run()
是 Python 中一個非常有用的工具,用于與系統(tǒng)命令交互。通過設(shè)置不同的參數(shù),我們可以輕松控制命令的執(zhí)行、捕獲其輸出、檢查其狀態(tài)以及處理可能的錯誤。在使用 check=True
時(shí),函數(shù)會自動處理失敗情況,通過拋出異常的方式提醒開發(fā)者注意到命令的失敗,這在編寫更穩(wěn)健的腳本時(shí)尤其有用。
使用 subprocess.run()
的一些最佳實(shí)踐包括:
- 優(yōu)先使用列表而不是字符串 作為命令,以避免潛在的 shell 注入風(fēng)險(xiǎn)。
- 結(jié)合
check=True
使用異常處理,這樣可以更好地處理命令執(zhí)行失敗的情況。 - 捕獲輸出并處理,確保命令的輸出被正確記錄或用于后續(xù)邏輯。
通過這些方法,我們可以充分利用 subprocess.run()
的功能,編寫高效且安全的 Python 腳本。
到此這篇關(guān)于Python中subprocess.run()執(zhí)行命令、檢查狀態(tài)與結(jié)果處理的文章就介紹到這了,更多相關(guān)Python subprocess.run()詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
總結(jié)Python連接CS2000的詳細(xì)步驟
今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識,文章圍繞著Python連接CS2000的詳細(xì)步驟展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06django下創(chuàng)建多個app并設(shè)置urls方法
在本篇文章里小編給大家分享的是一篇關(guān)于django下創(chuàng)建多個app并設(shè)置urls方法,需要的朋友們可以參考學(xué)習(xí)下。2020-08-08python如何實(shí)現(xiàn)單向鏈表及單向鏈表的反轉(zhuǎn)
這篇文章主要介紹了python如何實(shí)現(xiàn)單向鏈表及單向鏈表的反轉(zhuǎn),幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03python雙端隊(duì)列原理、實(shí)現(xiàn)與使用方法分析
這篇文章主要介紹了python雙端隊(duì)列原理、實(shí)現(xiàn)與使用方法,結(jié)合實(shí)例形式分析了Python雙端隊(duì)列的概念、原理、定義及使用方法,需要的朋友可以參考下2019-11-11Python數(shù)據(jù)結(jié)構(gòu)與算法中的棧詳解(2)
這篇文章主要為大家詳細(xì)介紹了Python中的棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03python re庫的正則表達(dá)式入門學(xué)習(xí)教程
這篇文章主要給大家介紹了關(guān)于python re庫的正則表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03