python執(zhí)行shell并獲取結(jié)果的詳細示例
在Python中執(zhí)行Shell命令并獲取其結(jié)果,通??梢允褂?code>subprocess模塊。這個模塊允許我們啟動新的進程,連接到它們的輸入/輸出/錯誤管道,并獲取它們的返回碼。下面是一個詳細的示例,展示了如何使用subprocess.run()函數(shù)來執(zhí)行Shell命令并獲取其輸出。
1. 示例一:使用subprocess.run()執(zhí)行l(wèi)s命令并獲取結(jié)果
這個示例將執(zhí)行ls命令(在Unix/Linux/macOS系統(tǒng)上列出當前目錄下的文件和文件夾),并捕獲命令的輸出和返回碼。
import subprocess
# 定義要執(zhí)行的命令
command = ['ls', '-l'] # 使用列表形式,更安全,可以避免shell注入攻擊
# 執(zhí)行命令
# capture_output=True 參數(shù)表示捕獲命令的輸出(stdout和stderr)
# text=True 參數(shù)表示將輸出作為文本處理(Python 3.7+),之前版本使用universal_newlines=True
result = subprocess.run(command, capture_output=True, text=True)
# 獲取命令的標準輸出
stdout = result.stdout
# 獲取命令的錯誤輸出(如果有的話)
stderr = result.stderr
# 獲取命令的返回碼
returncode = result.returncode
# 打印結(jié)果
print(f"標準輸出:\n{stdout}")
if stderr:
print(f"錯誤輸出:\n{stderr}")
print(f"返回碼: {returncode}")
# 注意:如果命令成功執(zhí)行,returncode通常為0;非0值表示有錯誤發(fā)生注意事項:
(1)安全性:本例中使用命令列表而非字符串來避免shell注入攻擊。當命令和參數(shù)以列表形式提供時,Python會直接將它們傳遞給系統(tǒng),不會通過shell解釋,從而減少了安全風險。
(2)文本與字節(jié):capture_output=True 和 text=True(或universal_newlines=True,在舊版本中)的組合使得輸出以文本(字符串)形式返回,而不是字節(jié)。這對于處理文本數(shù)據(jù)很方便,但如果我們需要處理二進制數(shù)據(jù)(如圖像或視頻文件),則可能需要以字節(jié)形式捕獲輸出。
(3)錯誤處理:通過檢查returncode可以判斷命令是否成功執(zhí)行。如果returncode不為0,則可能需要根據(jù)stderr中的信息來診斷問題。
(4)跨平臺兼容性:本示例中的ls -l命令是Unix/Linux/macOS系統(tǒng)特有的。在Windows系統(tǒng)上,我們可能需要執(zhí)行不同的命令(如dir),并可能需要調(diào)整命令的調(diào)用方式(例如,使用shell=True,但請注意這會增加安全風險)。
(5)性能考慮:頻繁地啟動外部進程可能會降低程序的性能。如果可能,盡量在Python內(nèi)部解決問題,或者考慮使用多線程/多進程來并行處理外部命令的調(diào)用。
2. 示例二:使用subprocess.run()函數(shù)來執(zhí)行Shell命令
以下是一個更詳細的代碼示例,它展示了如何在Python中使用subprocess.run()函數(shù)來執(zhí)行Shell命令(在這個例子中是ls -l),并處理可能出現(xiàn)的各種情況,包括成功執(zhí)行、命令不存在、以及捕獲標準輸出和錯誤輸出。
請注意,這個示例假設我們在一個Unix/Linux/macOS系統(tǒng)上運行,因為ls -l是這些系統(tǒng)的命令。如果我們在Windows上,我們可能需要替換為dir命令,并可能需要調(diào)整shell參數(shù)的使用(盡管通常建議避免使用shell=True以避免安全風險)。
import subprocess
def run_command(command):
"""
執(zhí)行給定的命令并返回其輸出和返回碼。
參數(shù):
- command: 要執(zhí)行的命令,作為列表傳遞(例如 ['ls', '-l']),以避免shell注入。
返回:
- output: 命令的標準輸出(如果有的話)。
- error: 命令的錯誤輸出(如果有的話)。
- returncode: 命令的返回碼。
"""
try:
# 使用subprocess.run()執(zhí)行命令
# capture_output=True表示捕獲stdout和stderr
# text=True表示將輸出作為文本處理(Python 3.7+)
result = subprocess.run(command, capture_output=True, text=True, check=True)
# 如果命令成功執(zhí)行(沒有異常),則返回其輸出和返回碼
return result.stdout, None, result.returncode
except subprocess.CalledProcessError as e:
# 如果命令執(zhí)行失?。ǚ祷卮a非0),則捕獲CalledProcessError異常
# 并返回錯誤輸出、標準輸出(如果有的話)和返回碼
return None, e.stderr, e.returncode
except Exception as e:
# 捕獲其他可能的異常(雖然在這個簡單的例子中可能不太常見)
return None, f"An unexpected error occurred: {e}", None
# 定義要執(zhí)行的命令
command = ['ls', '-l']
# 執(zhí)行命令并獲取結(jié)果
output, error, returncode = run_command(command)
# 根據(jù)返回的結(jié)果打印相應的信息
if output:
print("標準輸出:")
print(output)
if error:
print("錯誤輸出:")
print(error)
if returncode is not None:
print(f"返回碼: {returncode}")
if returncode == 0:
print("命令成功執(zhí)行。")
else:
print("命令執(zhí)行失敗。")在這個示例中,run_command函數(shù)封裝了subprocess.run()的調(diào)用,并處理了幾種可能的情況:
(1)命令成功執(zhí)行(返回碼為0):返回標準輸出、None作為錯誤輸出,以及返回碼。
(2)命令執(zhí)行失?。ǚ祷卮a非0):捕獲subprocess.CalledProcessError異常,并返回None作為標準輸出、錯誤輸出,以及返回碼。
(3)其他異常情況:捕獲并返回一條錯誤消息和None作為返回碼(雖然在這個特定的例子中,由于subprocess.run()通常只拋出CalledProcessError,所以這部分可能不會被執(zhí)行)。
請注意,subprocess.run()的check=True參數(shù)會在命令返回非零退出碼時自動拋出CalledProcessError異常,這使得我們可以在try-except塊中捕獲它。然而,在這個示例中,我選擇了顯式地捕獲異常,以便能夠更靈活地處理輸出和返回碼。如果我們只想在命令失敗時拋出異常,并且不關(guān)心錯誤處理的具體細節(jié),那么可以在調(diào)用subprocess.run()時設置check=True,并讓Python的默認異常處理機制來處理它。
3. shell編程及shell命令
3.1 Shell編程
Shell編程是指使用Shell(也稱為命令行解釋器或命令行界面)作為編程語言來編寫腳本的過程。Shell是Unix/Linux/macOS等類Unix操作系統(tǒng)中的一個特殊程序,它為用戶提供了一個與操作系統(tǒng)交互的環(huán)境。Shell腳本是一系列Shell命令的集合,這些命令被編寫在文本文件中,并通過Shell解釋器執(zhí)行,以實現(xiàn)自動化任務、批處理文件、管理系統(tǒng)資源等目的。
Shell腳本具有跨平臺性,因為它們主要依賴于Shell的功能和命令,而這些在大多數(shù)類Unix系統(tǒng)中都是相似的。然而,不同的Shell(如Bash、Zsh、Fish等)可能有自己的特性和擴展,因此編寫的腳本可能需要針對特定的Shell進行適配。
Shell編程通常包括變量定義、條件判斷、循環(huán)控制、函數(shù)調(diào)用等編程元素,但與傳統(tǒng)編程語言相比,Shell腳本的語法相對簡單且靈活。
3.2 Shell命令
Shell命令是用戶在Shell環(huán)境中輸入的指令,用于執(zhí)行各種操作,如文件管理、程序執(zhí)行、系統(tǒng)管理等。Shell命令可以是Shell內(nèi)置的,也可以是系統(tǒng)上的外部程序。
(1)內(nèi)置命令:由Shell本身提供的命令,這些命令在Shell啟動時就已經(jīng)加載到內(nèi)存中,因此執(zhí)行速度較快。內(nèi)置命令不依賴于系統(tǒng)上的其他程序,因此它們在系統(tǒng)啟動時就已經(jīng)可用。常見的內(nèi)置命令包括cd(改變目錄)、echo(顯示信息)、exit(退出Shell)等。
(2)外部命令:也稱為文件系統(tǒng)命令,這些命令是系統(tǒng)上獨立的程序,通常位于/bin、/usr/bin、/sbin、/usr/sbin等目錄下。當Shell需要執(zhí)行這些命令時,它會查找這些目錄來找到對應的程序并執(zhí)行。常見的外部命令包括ls(列出目錄內(nèi)容)、cp(復制文件或目錄)、mv(移動或重命名文件或目錄)等。
Shell命令可以通過管道(|)、重定向(>、<、>>)、命令替換(command 或 $(command))等機制進行組合,以實現(xiàn)更復雜的操作。例如,ls -l | grep '^d'命令會列出當前目錄下所有目錄的詳細信息(ls -l列出詳細信息,grep '^d'篩選出以d開頭的行,即目錄)。
Shell編程和Shell命令是Unix/Linux/macOS等系統(tǒng)用戶日常工作中不可或缺的工具,它們能夠極大地提高用戶的工作效率,并幫助用戶自動化地完成各種任務。
3.3 如何使用Shell編程
使用Shell編程主要涉及到編寫Shell腳本,這些腳本包含了一系列的Shell命令,通過Shell解釋器執(zhí)行以實現(xiàn)特定的功能。以下是使用Shell編程的基本步驟:
3.3.1 選擇Shell
首先,我們需要確定使用哪種Shell。常見的Shell有Bash(Bourne Again SHell,大多數(shù)Linux發(fā)行版的默認Shell)、Zsh(Z Shell,具有許多增強特性和更好的用戶體驗)、Fish(Friendly Interactive SHell,以用戶友好和易于學習而著稱)等。對于初學者來說,Bash是一個很好的起點,因為它廣泛可用且文檔豐富。
3.3.2 編寫Shell腳本
Shell腳本通常保存在以.sh為擴展名的文件中。我們可以使用任何文本編輯器來編寫Shell腳本,比如nano、vim、emacs或簡單的echo和重定向。
以下是一個簡單的Shell腳本示例,它打印出“Hello, World!”:
#!/bin/bash # 這是一個簡單的Shell腳本示例 echo "Hello, World!"
在腳本的第一行,#!/bin/bash被稱為shebang,它告訴系統(tǒng)這個腳本應該使用哪個解釋器來執(zhí)行。在這個例子中,它指定了Bash。
3.3.3 保存腳本
將我們的腳本保存到文件中,例如hello.sh。
3.3.4 賦予執(zhí)行權(quán)限
在Linux或macOS上,我們需要給腳本文件賦予執(zhí)行權(quán)限,以便能夠直接運行它。我們可以使用chmod命令來做到這一點:
chmod +x hello.sh
這個命令會給hello.sh文件添加執(zhí)行權(quán)限。
3.3.5 運行腳本
現(xiàn)在,我們可以通過以下兩種方式之一來運行我們的腳本:
直接通過腳本的路徑和名稱(如果腳本具有執(zhí)行權(quán)限):
./hello.sh
注意,我們需要使用./來指定腳本位于當前目錄下。
使用Shell解釋器來執(zhí)行腳本(無論腳本是否具有執(zhí)行權(quán)限):
bash hello.sh
這個命令會告訴Bash解釋器來執(zhí)行hello.sh腳本中的命令。
到此這篇關(guān)于python執(zhí)行shell并獲取結(jié)果的文章就介紹到這了,更多相關(guān)python執(zhí)行shell并獲取結(jié)果內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python執(zhí)行shell腳本的四種方法
- Python使用paramiko連接遠程服務器執(zhí)行Shell命令的實現(xiàn)
- 解決python 執(zhí)行shell命令無法獲取返回值的問題
- python ssh 執(zhí)行shell命令的示例
- 使用python執(zhí)行shell腳本 并動態(tài)傳參 及subprocess的使用詳解
- python3模擬實現(xiàn)xshell遠程執(zhí)行l(wèi)inux命令的方法
- python3編寫ThinkPHP命令執(zhí)行Getshell的方法
- python操作數(shù)據(jù)庫獲取結(jié)果之fetchone和fetchall的區(qū)別說明
相關(guān)文章
python監(jiān)測當前聯(lián)網(wǎng)狀態(tài)并連接的實例
今天小編就為大家分享一篇python監(jiān)測當前聯(lián)網(wǎng)狀態(tài)并連接的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
如何解決pycharm中用matplotlib畫圖不顯示中文的問題
這篇文章主要介紹了如何解決pycharm中用matplotlib畫圖不顯示中文的問題,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-06-06
python優(yōu)化數(shù)據(jù)預處理方法Pandas pipe詳解
在本文中,我們將重點討論一個將多個預處理操作組織成單個操作的特定函數(shù):pipe。我將通過示例方式來展示如何使用它,讓我們從數(shù)據(jù)創(chuàng)建數(shù)據(jù)幀開始吧2021-11-11

