一文詳解Python中的subprocess模塊
subprocess模塊簡(jiǎn)介
subprocess模塊是Python標(biāo)準(zhǔn)庫(kù)的一部分,提供了一個(gè)跨平臺(tái)的方法來(lái)生成新進(jìn)程、連接其輸入/輸出/錯(cuò)誤管道,并獲取其返回碼。該模塊旨在替代舊的os.system、os.spawn*、os.popen*和commands模塊,提供一個(gè)更強(qiáng)大和靈活的接口。
常用函數(shù)
subprocess模塊中有幾個(gè)常用的函數(shù)和類(lèi),它們是進(jìn)行進(jìn)程管理和管道通信的核心:
subprocess.run()
subprocess.Popen()
subprocess.call()
subprocess.check_call()
subprocess.check_output()
subprocess.DEVNULL
subprocess.PIPE
subprocess.STDOUT
示例代碼
import subprocess # 運(yùn)行一個(gè)命令并等待其完成 subprocess.run(["ls", "-l"]) # 使用Popen對(duì)象啟動(dòng)和管理進(jìn)程 process = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE) output, error = process.communicate() print(output.decode())
執(zhí)行外部命令
使用subprocess.run()
subprocess.run()
是執(zhí)行外部命令的推薦方式。它接受一個(gè)命令序列或字符串,返回一個(gè)CompletedProcess
實(shí)例,包含了命令的執(zhí)行結(jié)果。
示例代碼
import subprocess # 執(zhí)行命令并等待完成 result = subprocess.run(["echo", "Hello, World!"], capture_output=True, text=True) print(result.stdout)
使用subprocess.call()
subprocess.call()
用于執(zhí)行命令并返回其退出狀態(tài)。它類(lèi)似于subprocess.run()
,但不會(huì)返回CompletedProcess
實(shí)例。
示例代碼
import subprocess # 執(zhí)行命令并返回退出狀態(tài) return_code = subprocess.call(["ls", "-l"]) print(f"Return code: {return_code}")
使用subprocess.check_call()
subprocess.check_call()
類(lèi)似于subprocess.call()
,但如果命令返回非零退出狀態(tài),它會(huì)引發(fā)CalledProcessError
異常。
示例代碼
import subprocess try: subprocess.check_call(["ls", "-l"]) except subprocess.CalledProcessError as e: print(f"Command failed with return code {e.returncode}")
使用subprocess.check_output()
subprocess.check_output()
執(zhí)行命令并返回其輸出。如果命令返回非零退出狀態(tài),它會(huì)引發(fā)CalledProcessError
異常。
示例代碼
import subprocess try: output = subprocess.check_output(["echo", "Hello, World!"], text=True) print(output) except subprocess.CalledProcessError as e: print(f"Command failed with return code {e.returncode}")
管道通信
subprocess
模塊允許開(kāi)發(fā)者通過(guò)管道連接多個(gè)進(jìn)程,實(shí)現(xiàn)進(jìn)程間通信。使用subprocess.PIPE
可以將子進(jìn)程的輸入/輸出/錯(cuò)誤重定向到父進(jìn)程。
示例代碼
import subprocess # 將子進(jìn)程的輸出重定向到父進(jìn)程 process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE) output, error = process.communicate() print(output.decode())
管道連接示例
import subprocess # 使用管道連接兩個(gè)命令 p1 = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE) p2 = subprocess.Popen(["grep", "Hello"], stdin=p1.stdout, stdout=subprocess.PIPE) p1.stdout.close() # 允許p1關(guān)閉它的輸出管道 output, error = p2.communicate() print(output.decode())
子進(jìn)程管理
終止子進(jìn)程
可以使用Popen
對(duì)象的terminate()
和kill()
方法終止子進(jìn)程。
示例代碼
import subprocess import time # 啟動(dòng)一個(gè)長(zhǎng)時(shí)間運(yùn)行的進(jìn)程 process = subprocess.Popen(["sleep", "10"]) # 等待2秒后終止進(jìn)程 time.sleep(2) process.terminate() process.wait() print("Process terminated")
獲取子進(jìn)程的返回碼
可以使用Popen
對(duì)象的returncode
屬性獲取子進(jìn)程的返回碼。
示例代碼
import subprocess process = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE) process.wait() print(f"Return code: {process.returncode}")
錯(cuò)誤處理
捕獲異常
在執(zhí)行外部命令時(shí),可能會(huì)遇到各種異常情況。subprocess
模塊提供了CalledProcessError
和TimeoutExpired
異常,便于開(kāi)發(fā)者處理錯(cuò)誤。
示例代碼
import subprocess try: subprocess.check_call(["false"]) except subprocess.CalledProcessError as e: print(f"Command failed with return code {e.returncode}")
超時(shí)處理
可以使用timeout
參數(shù)設(shè)置命令的超時(shí)時(shí)間,如果命令在指定時(shí)間內(nèi)沒(méi)有完成,將引發(fā)TimeoutExpired
異常。
示例代碼
import subprocess try: subprocess.run(["sleep", "10"], timeout=5) except subprocess.TimeoutExpired: print("Command timed out")
實(shí)際應(yīng)用示例
運(yùn)行shell命令
在實(shí)際應(yīng)用中,subprocess
模塊常用于運(yùn)行shell命令。使用shell=True
參數(shù)可以在shell中執(zhí)行命令。
示例代碼
import subprocess result = subprocess.run("ls -l | grep .py", shell=True, capture_output=True, text=True) print(result.stdout)
備份數(shù)據(jù)庫(kù)
可以使用subprocess
模塊執(zhí)行數(shù)據(jù)庫(kù)備份命令,將備份文件保存到指定路徑。
示例代碼
import subprocess command = ["mysqldump", "-u", "root", "-p", "database_name"] with open("backup.sql", "w") as f: result = subprocess.run(command, stdout=f) if result.returncode == 0: print("Backup successful") else: print("Backup failed")
自動(dòng)化腳本
subprocess
模塊可以用于編寫(xiě)自動(dòng)化腳本,執(zhí)行一系列的命令完成特定任務(wù)。
示例代碼
import subprocess def run_commands(commands): for command in commands: result = subprocess.run(command, shell=True, capture_output=True, text=True) if result.returncode != 0: print(f"Command failed: {command}") print(result.stderr) break else: print(result.stdout) commands = [ "echo 'Starting automation script'", "mkdir -p /tmp/test_directory", "touch /tmp/test_directory/test_file", "echo 'Automation script completed'" ] run_commands(commands)
最佳實(shí)踐
- 避免使用
shell=True
: 除非必要,否則盡量避免使用shell=True
,以減少安全風(fēng)險(xiǎn)。 - 使用完整路徑: 在命令中使用完整路徑,以確保命令能夠正確執(zhí)行。
- 處理異常: 始終捕獲并處理可能出現(xiàn)的異常,確保程序的健壯性。
- 設(shè)置超時(shí): 對(duì)長(zhǎng)時(shí)間運(yùn)行的命令設(shè)置超時(shí),以避免程序掛起。
- 使用上下文管理器: 使用上下文管理器管理文件對(duì)象,確保資源正確釋放。
示例代碼
import subprocess def safe_run_command(command, timeout=10): try: result = subprocess.run(command, capture_output=True, text=True, timeout=timeout) result.check_returncode() return result.stdout except subprocess.CalledProcessError as e: print(f"Command '{e.cmd}' failed with return code {e.returncode}") except subprocess.TimeoutExpired as e: print(f"Command '{e.cmd}' timed out after {e.timeout} seconds") output = safe_run_command(["ls", "-l"]) print(output)
結(jié)論
subprocess模塊是Python中執(zhí)行外部命令和管理子進(jìn)程的強(qiáng)大工具。通過(guò)學(xué)習(xí)并掌握subprocess模塊的使用,可以編寫(xiě)出高效、可靠的自動(dòng)化腳本和系統(tǒng)
管理工具。本文詳細(xì)介紹了subprocess模塊的基本概念、常用函數(shù)、管道通信、子進(jìn)程管理、錯(cuò)誤處理及實(shí)際應(yīng)用示例,希望對(duì)讀者有所幫助。通過(guò)不斷實(shí)踐和應(yīng)用這些知識(shí),開(kāi)發(fā)者能夠提高代碼質(zhì)量,減少錯(cuò)誤,提升開(kāi)發(fā)效率。
以上就是一文詳解Python中的subprocess模塊的詳細(xì)內(nèi)容,更多關(guān)于Python subprocess模塊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)sublime3的less編譯插件示例
這篇文章主要介紹了python實(shí)現(xiàn)sublime3的less編譯插件示例的相關(guān)資料2014-04-04Pycharm中無(wú)法使用pip安裝的包問(wèn)題解決方案
本文主要介紹了Pycharm中無(wú)法使用pip安裝的包問(wèn)題解決方案,在終端通過(guò)pip裝好包以后,在pycharm中導(dǎo)入包時(shí),依然會(huì)報(bào)錯(cuò),下面就來(lái)介紹一下解決方法2023-09-09Python產(chǎn)生一個(gè)數(shù)值范圍內(nèi)的不重復(fù)的隨機(jī)數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了Python產(chǎn)生一個(gè)數(shù)值范圍內(nèi)的不重復(fù)的隨機(jī)數(shù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08python 截取XML中bndbox的坐標(biāo)中的圖像,另存為jpg的實(shí)例
這篇文章主要介紹了python 截取XML中bndbox的坐標(biāo)中的圖像,另存為jpg的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03python中的set實(shí)現(xiàn)不重復(fù)的排序原理
這篇文章主要介紹了python中的set實(shí)現(xiàn)不重復(fù)的排序原理,需要的朋友可以參考下2018-01-01探究Python的Tornado框架對(duì)子域名和泛域名的支持
這篇文章主要介紹了探究Python的Tornado框架對(duì)子域名和泛域名的支持,Tornado作為一個(gè)典型的異步框架、在Python開(kāi)發(fā)者中的人氣相當(dāng)高,需要的朋友可以參考下2015-05-05利用Python搶回在螞蟻森林逝去的能量(實(shí)現(xiàn)代碼)
螞蟻森林是一項(xiàng)旨在帶動(dòng)公眾低碳減排的公益項(xiàng)目,每個(gè)人的低碳行為在螞蟻森林里可計(jì)為"綠色能量",很多小伙伴都玩過(guò),今天小編給大家分享一篇教程關(guān)于Python搶回在螞蟻森林逝去的能量,感興趣的朋友跟隨小編一起看看吧2022-03-03

Django網(wǎng)絡(luò)框架之創(chuàng)建虛擬開(kāi)發(fā)環(huán)境操作示例