Python中如何調(diào)用系統(tǒng)命令和進(jìn)程
在Python編程中,subprocess庫(kù)是一個(gè)功能強(qiáng)大的工具,它允許我們創(chuàng)建新進(jìn)程、連接到其輸入/輸出/錯(cuò)誤管道,并獲取其返回代碼。本文將詳細(xì)介紹subprocess庫(kù)的功能、應(yīng)用場(chǎng)景,并通過代碼示例進(jìn)行說(shuō)明。此外,我們還將對(duì)比subprocess與os.system和os.popen的區(qū)別。
1. subprocess庫(kù)的功能
subprocess庫(kù)提供了多種功能,以滿足不同的需求。主要功能包括:
- 運(yùn)行外部命令:可以執(zhí)行系統(tǒng)命令或調(diào)用其他可執(zhí)行文件。
- 交互式進(jìn)程通信:?jiǎn)?dòng)外部進(jìn)程,并通過管道與其進(jìn)行交互,發(fā)送輸入并獲取輸出。
- 管道和重定向:創(chuàng)建一個(gè)進(jìn)程的輸出作為另一個(gè)進(jìn)程的輸入,或重定向進(jìn)程的輸出到文件。
- 進(jìn)程管理:監(jiān)控進(jìn)程狀態(tài),等待進(jìn)程結(jié)束,或終止進(jìn)程。
2. 應(yīng)用場(chǎng)景及代碼示例
2.1 運(yùn)行外部命令
subprocess.run()是一個(gè)高級(jí)接口,用于執(zhí)行外部命令并等待其完成。它返回一個(gè)CompletedProcess對(duì)象,包含執(zhí)行結(jié)果的相關(guān)信息。
代碼示例:
import subprocess
# 執(zhí)行外部命令并捕獲輸出
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print("Return Code:", result.returncode)
print("Standard Output:", result.stdout)
print("Standard Error:", result.stderr)
解釋:
['ls', '-l']:要執(zhí)行的命令和參數(shù)。
capture_output=True:捕獲子進(jìn)程的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。
text=True:以文本模式處理輸入/輸出。
2.2 交互式進(jìn)程通信
subprocess.Popen()提供了更靈活的方式來(lái)管理子進(jìn)程,可以通過管道發(fā)送輸入數(shù)據(jù)給子進(jìn)程,并獲取其輸出。
代碼示例:
import subprocess
# 啟動(dòng)一個(gè)子進(jìn)程并與它交互
process = subprocess.Popen(['grep', 'pattern'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
output, _ = process.communicate(input='some input data\n')
print("Output:", output)
解釋:
['grep', 'pattern']:要執(zhí)行的命令和參數(shù)。
stdin=subprocess.PIPE:通過管道向子進(jìn)程發(fā)送數(shù)據(jù)。
stdout=subprocess.PIPE:通過管道捕獲子進(jìn)程的輸出。
process.communicate(input='some input data\n'):向子進(jìn)程發(fā)送輸入數(shù)據(jù)并獲取輸出。
2.3 管道和重定向
subprocess庫(kù)可以輕松創(chuàng)建管道,將一個(gè)進(jìn)程的輸出重定向到另一個(gè)進(jìn)程的輸入。
代碼示例:
import subprocess
# 第一個(gè)命令
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
# 第二個(gè)命令,通過管道傳輸數(shù)據(jù)
p2 = subprocess.Popen(['grep', '.py'], stdin=p1.stdout, stdout=subprocess.PIPE)
output = p2.communicate()[0]
print('Python文件列表:')
print(output.decode())
解釋:
p1.stdout=subprocess.PIPE:將p1的輸出作為管道。
p2.stdin=p1.stdout:將p1的輸出作為p2的輸入。
p2.communicate():獲取p2的最終輸出。
2.4 進(jìn)程管理
subprocess.Popen()還提供了多種方法來(lái)管理進(jìn)程,如poll()、terminate()、kill()等。
代碼示例:
import subprocess
# 啟動(dòng)一個(gè)子進(jìn)程
process = subprocess.Popen(['sleep', '10'])
# 檢查進(jìn)程是否仍在運(yùn)行
print("Process is running:", process.poll() is None)
# 終止進(jìn)程
process.terminate()
# 等待進(jìn)程結(jié)束
process.wait()
print("Process has terminated")
解釋:
process.poll():檢查進(jìn)程是否仍在運(yùn)行,返回None表示仍在運(yùn)行,返回退出碼表示已結(jié)束。
process.terminate():請(qǐng)求終止進(jìn)程。
process.wait():等待進(jìn)程結(jié)束。
3. 與os.system和os.popen的對(duì)比
雖然os.system和os.popen也可以用于執(zhí)行外部命令并與進(jìn)程進(jìn)行交互,但它們與subprocess相比存在一些限制和不足。
3.1 os.system
os.system是Python中最簡(jiǎn)單的執(zhí)行外部命令的方法,但它有幾個(gè)顯著的缺點(diǎn):
- 無(wú)法捕獲輸出:os.system只能執(zhí)行命令,無(wú)法直接捕獲其輸出或錯(cuò)誤。輸出會(huì)直接打印到控制臺(tái)。
- 返回碼有限:它返回一個(gè)8位的字節(jié),表示命令的退出狀態(tài),這可能導(dǎo)致狀態(tài)碼被截?cái)唷?/li>
- 安全性問題:使用字符串拼接來(lái)構(gòu)建命令可能會(huì)導(dǎo)致安全風(fēng)險(xiǎn),如命令注入。
代碼示例:
import os
# 執(zhí)行外部命令
exit_code = os.system('ls -l')
print("Exit Code:", exit_code)
3.2 os.popen
os.popen允許我們打開一個(gè)與命令的管道,從中讀取輸出。與os.system相比,它可以捕獲輸出,但仍然有一些限制:
- 單向通信:它只能用于從命令讀取輸出,不能發(fā)送輸入。
- 資源管理:需要手動(dòng)關(guān)閉文件對(duì)象,否則可能導(dǎo)致資源泄漏。
- 安全性問題:同樣存在命令注入的風(fēng)險(xiǎn)。
代碼示例:
import os
# 打開一個(gè)與命令的管道并讀取輸出
process = os.popen('ls -l')
output = process.read()
process.close()
print("Output:", output)
3.3 subprocess的優(yōu)勢(shì)
與os.system和os.popen相比,subprocess提供了以下優(yōu)勢(shì):
更強(qiáng)大的功能:支持雙向通信、管道、重定向等高級(jí)功能。
更好的資源管理:可以自動(dòng)管理文件描述符和進(jìn)程,減少資源泄漏的風(fēng)險(xiǎn)。
更高的安全性:通過列表形式傳遞命令和參數(shù),避免了命令注入的風(fēng)險(xiǎn)。
更豐富的返回信息:subprocess.run()返回一個(gè)CompletedProcess對(duì)象,包含退出碼、輸出和錯(cuò)誤等信息。
4. 總結(jié)
subprocess庫(kù)是Python中一個(gè)非常強(qiáng)大的工具,它提供了靈活而強(qiáng)大的進(jìn)程管理功能。與os.system和os.popen相比,subprocess在功能、資源管理、安全性和返回信息方面都具有顯著優(yōu)勢(shì)。無(wú)論是簡(jiǎn)單的命令執(zhí)行還是復(fù)雜的進(jìn)程管理,subprocess庫(kù)都能滿足我們的需求。因此,在需要執(zhí)行外部命令或與進(jìn)程進(jìn)行交互時(shí),推薦使用subprocess庫(kù)。
到此這篇關(guān)于Python中如何調(diào)用系統(tǒng)命令和進(jìn)程的文章就介紹到這了,更多相關(guān)Python調(diào)用系統(tǒng)命令和進(jìn)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中pivot()函數(shù)基礎(chǔ)知識(shí)點(diǎn)
在本篇內(nèi)容里小編給大家分享的是一篇關(guān)于python中pivot()函數(shù)基礎(chǔ)知識(shí)點(diǎn)內(nèi)容,對(duì)此有興趣的朋友們可以參考學(xué)習(xí)下。2021-01-01
使用Python開發(fā)一個(gè)Word操作助手的實(shí)戰(zhàn)指南(附源碼)
這篇文章主要介紹了Python版Word助手,這是一款基于Python開發(fā)的實(shí)用工具,旨在簡(jiǎn)化Microsoft?Word相關(guān)操作,如PDF與Word文檔互轉(zhuǎn)、提取Word文檔目錄等,感興趣的小伙伴可以了解下2025-12-12
python+OpenCV實(shí)現(xiàn)圖像拼接
這篇文章主要為大家詳細(xì)介紹了python+OpenCV實(shí)現(xiàn)圖像拼接,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
使用python-opencv讀取視頻,計(jì)算視頻總幀數(shù)及FPS的實(shí)現(xiàn)
今天小編就為大家分享一篇使用python-opencv讀取視頻,計(jì)算視頻總幀數(shù)及FPS的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2019-12-12
python使用smtplib模塊通過gmail實(shí)現(xiàn)郵件發(fā)送的方法
這篇文章主要介紹了python使用smtplib模塊通過gmail實(shí)現(xiàn)郵件發(fā)送的方法,涉及Python使用smtplib模塊發(fā)送郵件的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05
bat和python批量重命名文件的實(shí)現(xiàn)代碼
這篇文章主要介紹了bat和python批量重命名文件的實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-05-05
使用scrapy實(shí)現(xiàn)爬網(wǎng)站例子和實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(蜘蛛)的步驟
本文分二個(gè)示例,第一個(gè)是個(gè)簡(jiǎn)單的爬網(wǎng)站的小例子,第二個(gè)例子實(shí)現(xiàn)目是從一個(gè)網(wǎng)站的列表頁(yè)抓取文章列表,然后存入數(shù)據(jù)庫(kù)中,數(shù)據(jù)庫(kù)包括文章標(biāo)題、鏈接、時(shí)間,大家參考使用吧2014-01-01
零基礎(chǔ)寫python爬蟲之爬蟲框架Scrapy安裝配置
Scrapy是一個(gè)使用Python編寫的,輕量級(jí)的,簡(jiǎn)單輕巧,并且使用起來(lái)非常的方便。使用Scrapy可以很方便的完成網(wǎng)上數(shù)據(jù)的采集工作,它為我們完成了大量的工作,而不需要自己費(fèi)大力氣去開發(fā)。2014-11-11

