python執(zhí)行shell并獲取結果的詳細示例
在Python中執(zhí)行Shell命令并獲取其結果,通??梢允褂?code>subprocess模塊。這個模塊允許我們啟動新的進程,連接到它們的輸入/輸出/錯誤管道,并獲取它們的返回碼。下面是一個詳細的示例,展示了如何使用subprocess.run()
函數(shù)來執(zhí)行Shell命令并獲取其輸出。
1. 示例一:使用subprocess.run()執(zhí)行l(wèi)s命令并獲取結果
這個示例將執(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 # 打印結果 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
),并可能需要調整命令的調用方式(例如,使用shell=True
,但請注意這會增加安全風險)。
(5)性能考慮:頻繁地啟動外部進程可能會降低程序的性能。如果可能,盡量在Python內部解決問題,或者考慮使用多線程/多進程來并行處理外部命令的調用。
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
命令,并可能需要調整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í)行失敗(返回碼非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í)行命令并獲取結果 output, error, returncode = run_command(command) # 根據(jù)返回的結果打印相應的信息 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()
的調用,并處理了幾種可能的情況:
(1)命令成功執(zhí)行(返回碼為0):返回標準輸出、None
作為錯誤輸出,以及返回碼。
(2)命令執(zhí)行失敗(返回碼非0):捕獲subprocess.CalledProcessError
異常,并返回None
作為標準輸出、錯誤輸出,以及返回碼。
(3)其他異常情況:捕獲并返回一條錯誤消息和None
作為返回碼(雖然在這個特定的例子中,由于subprocess.run()
通常只拋出CalledProcessError
,所以這部分可能不會被執(zhí)行)。
請注意,subprocess.run()
的check=True
參數(shù)會在命令返回非零退出碼時自動拋出CalledProcessError
異常,這使得我們可以在try-except
塊中捕獲它。然而,在這個示例中,我選擇了顯式地捕獲異常,以便能夠更靈活地處理輸出和返回碼。如果我們只想在命令失敗時拋出異常,并且不關心錯誤處理的具體細節(jié),那么可以在調用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ù)調用等編程元素,但與傳統(tǒng)編程語言相比,Shell腳本的語法相對簡單且靈活。
3.2 Shell命令
Shell命令是用戶在Shell環(huán)境中輸入的指令,用于執(zhí)行各種操作,如文件管理、程序執(zhí)行、系統(tǒng)管理等。Shell命令可以是Shell內置的,也可以是系統(tǒng)上的外部程序。
(1)內置命令:由Shell本身提供的命令,這些命令在Shell啟動時就已經加載到內存中,因此執(zhí)行速度較快。內置命令不依賴于系統(tǒng)上的其他程序,因此它們在系統(tǒng)啟動時就已經可用。常見的內置命令包括cd
(改變目錄)、echo
(顯示信息)、exit
(退出Shell)等。
(2)外部命令:也稱為文件系統(tǒng)命令,這些命令是系統(tǒng)上獨立的程序,通常位于/bin
、/usr/bin
、/sbin
、/usr/sbin
等目錄下。當Shell需要執(zhí)行這些命令時,它會查找這些目錄來找到對應的程序并執(zhí)行。常見的外部命令包括ls
(列出目錄內容)、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í)行權限
在Linux或macOS上,我們需要給腳本文件賦予執(zhí)行權限,以便能夠直接運行它。我們可以使用chmod
命令來做到這一點:
chmod +x hello.sh
這個命令會給hello.sh
文件添加執(zhí)行權限。
3.3.5 運行腳本
現(xiàn)在,我們可以通過以下兩種方式之一來運行我們的腳本:
直接通過腳本的路徑和名稱(如果腳本具有執(zhí)行權限):
./hello.sh
注意,我們需要使用./
來指定腳本位于當前目錄下。
使用Shell解釋器來執(zhí)行腳本(無論腳本是否具有執(zhí)行權限):
bash hello.sh
這個命令會告訴Bash解釋器來執(zhí)行hello.sh
腳本中的命令。
到此這篇關于python執(zhí)行shell并獲取結果的文章就介紹到這了,更多相關python執(zhí)行shell并獲取結果內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 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ù)庫獲取結果之fetchone和fetchall的區(qū)別說明
相關文章
Python+matplotlib實現(xiàn)循環(huán)作圖的方法詳解
這篇文章主要為大家介紹了Python如何利用matplotlib實現(xiàn)循環(huán)作圖的,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習學習2022-06-06基于Python實現(xiàn)簡易學生信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了python實現(xiàn)簡易學生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07超好玩的"隔空操物"通過Python?MediaPipe庫實現(xiàn)
這篇文章主要介紹了python+mediapipe+opencv實現(xiàn)手部關鍵點檢測功能(手勢識別),本文僅僅簡單介紹了mediapipe的使用,而mediapipe提供了大量關于圖像識別等的方法,需要的朋友可以參考下2022-01-01Python連接數(shù)據(jù)庫使用matplotlib畫柱形圖
這篇文章主要介紹了Python連接數(shù)據(jù)庫使用matplotlib畫柱形圖,文章通過實例展開對主題的相關介紹。具有一定的知識參考價值性,感興趣的小伙伴可以參考一下2022-06-06