淺談Python調(diào)用Shell腳本的三種常用方式
一、通過(guò) Python 來(lái)調(diào)用 Shell 腳本的三種常用方式
三種方式的優(yōu)缺點(diǎn)
| os.system | subprocess.run | subprocess.Popen | |
|---|---|---|---|
| 是否需要解析參數(shù) | no | yes | yes |
| 同步執(zhí)行(等待Shell執(zhí)行結(jié)果) | yes | yes | no |
| 能夠獲得 shell 的輸入和輸出 | no | yes | yes |
| Shell 執(zhí)行結(jié)果返回值 | return value | object | object |
os.system
import os
return_code=os.system('ls -al .')
print(return_code)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
總用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:56 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r-- 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2442 8月 11 00:56 test.py
0
也會(huì)將Shell語(yǔ)句的輸出輸出到的 Python的命令控制臺(tái)中。
但是 Python 的能夠獲取的返回值,是數(shù)字,0 代表 Shell 語(yǔ)句/腳本的執(zhí)行成功,否則表示Shell執(zhí)行的狀態(tài)值。
適用于不需要詳細(xì)的返回信息的 shell 腳本
傳入 Shell 命令的參數(shù),都是完整的 String。
subprocess.run(推薦)
1 、 能夠相當(dāng)方便的控制 shell 命令的輸入和輸出
- 1 傳入的參數(shù)是一個(gè) 數(shù)組 而不是字符串。
import subprocess return_code=subprocess.run(['ls','-al','.']) print(return_code)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
總用量 20
drwxrwxr-x 3 topeet topeet 4096 8月 11 01:00 .
drwxrwxr-x 6 topeet topeet 4096 7月 27 06:27 …
drwxrwxr-x 3 topeet topeet 4096 8月 11 00:36 .idea
-rw-rw-r-- 1 topeet topeet 504 7月 27 07:35 main.py
-rwxrwxr-x 1 topeet topeet 2533 8月 11 01:00 test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
- 2 執(zhí)行返回的結(jié)果是一個(gè)CompletedProcess對(duì)象
2 、忽略shell 腳本執(zhí)行的結(jié)果
import subprocess return_code=subprocess.run(['ls','-al','.'],stdout=subprocess.DEVNULL) print(return_code)
(base) topeet@ubuntu:~/test/python$ python test.py
CompletedProcess(args=['ls', '-al', '.'], returncode=0)
- 2 輸出結(jié)果就僅有 Python 程序運(yùn)行出的結(jié)果。
3 、指定 shell 命令的輸入?yún)?shù)(通過(guò) input 參數(shù)來(lái)傳入)
import subprocess useless_cat_call=subprocess.run(['cat'],stdout=subprocess.PIPE,text=True,input="Hello") print(useless_cat_call.stdout)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
Hello
- stdout=subprocess.PIPE 告訴 Python,重定向 Shell 命令的輸出,并且這部分輸出可以被后面的 Python 程序所調(diào)用。
- text=True 告訴 Python,將 shell 命令的執(zhí)行的 stdout 和 stderr 當(dāng)成字符串. 默認(rèn)是當(dāng)成 bytes.
- input="Hello from the other side" 告訴 Python,shell 命令的輸入?yún)?shù).
4 、開啟 shell 命令的執(zhí)行校驗(yàn)
- 1 當(dāng) shell 的執(zhí)行出現(xiàn)任何問題,都會(huì)拋出一個(gè)異常。
import subprocess
failed_command=subprocess.run(['false'],text=True)
print("The exit code was: %d" % failed_command.returncode)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
The exit code was:1
5、subprocess.run方法參數(shù)的介紹
核心控制參數(shù)??
- ??args??
- ??作用??:指定要執(zhí)行的命令,支持??列表??(推薦)或??字符串??形式。
- ??注意??:列表形式可避免命令注入風(fēng)險(xiǎn);字符串形式必須設(shè)置 shell=True。
subprocess.run(["ls", "-l"]) # 安全方式(列表)[1,3]
subprocess.run("ls -l", shell=True) # 字符串需配合 shell=True[5]
- ??shell??
- ??作用??:是否通過(guò)系統(tǒng) Shell(如 /bin/sh或 cmd.exe)執(zhí)行命令。
- ??風(fēng)險(xiǎn)??:shell=True可能引發(fā)安全漏洞(如執(zhí)行惡意輸入),非必要不啟用
- ??適用場(chǎng)景??:需 Shell 特性(如通配符 *、管道 |)時(shí)使用。
- ??timeout??
- ??作用??:設(shè)置命令超時(shí)時(shí)間(秒),超時(shí)拋出 TimeoutExpired異常。
- ??示例??:
try:
subprocess.run(["sleep", "10"], timeout=5)
except TimeoutExpired:
print("命令超時(shí)!") # 5秒后中斷[3,6]
輸入/輸出處理參數(shù)??
- ??stdin、stdout、stderr??
- ??作用??:控制子進(jìn)程的標(biāo)準(zhǔn)流,可選值:
- subprocess.PIPE:捕獲數(shù)據(jù)流(通過(guò) result.stdout訪問)
- subprocess.DEVNULL:丟棄輸出(類似 /dev/null)。
- 文件對(duì)象:重定向到文件。
- ??示例??:
result = subprocess.run(["ls"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- ??capture_output??
- ??作用??:簡(jiǎn)化輸出捕獲(等價(jià)于設(shè)置 stdout=PIPE, stderr=PIPE)。
- ??沖突??:不可與 stdout/stderr同時(shí)使用
- ??input??
- ??作用??:向子進(jìn)程的 stdin 傳遞數(shù)據(jù),需配合 stdin=PIPE(自動(dòng)啟用)。
- ??數(shù)據(jù)類型??:
- text=True時(shí):??字符串??(如 input="Hello")
- 默認(rèn):??字節(jié)流??(如 input=b"Hello")。
- ??text/ encoding??
- ??作用??:控制輸入/輸出的文本模式:
- text=True:輸入/輸出自動(dòng)轉(zhuǎn)為字符串(等價(jià)于 universal_newlines=True)
- encoding="utf-8":指定編解碼方式(如處理中文)。
執(zhí)行環(huán)境參數(shù)??
- ??cwd??
- ??作用??:設(shè)置子進(jìn)程的工作目錄。
- ??示例??:
subprocess.run(["pwd"], cwd="/tmp") # 輸出 "/tmp
- ??env??
- ??作用??:自定義環(huán)境變量(字典形式),默認(rèn)繼承父進(jìn)程環(huán)境。
- ??示例??:
env = {"PATH": "/usr/bin", "MY_VAR": "test"}
subprocess.run(["echo", "$MY_VAR"], env=env, shell=True)[4](@ref)
異常與狀態(tài)處理??
- ??check??
- ??作用??:若子進(jìn)程返回??非零退出碼??,拋出 CalledProcessError異常。
- ??示例??:
try:
subprocess.run(["false"], check=True) # 總是失敗的命令
except CalledProcessError as e:
print(f"錯(cuò)誤碼: {e.returncode}, 錯(cuò)誤: {e.stderr}")
- ??返回值 CompletedProcess??
- ??屬性??:
- returncode:退出狀態(tài)碼(0 表示成功)。
- stdout/stderr:捕獲的輸出(文本或字節(jié)流)。
- args:執(zhí)行的命令
- ??方法??:
- check_returncode():非零退出碼時(shí)拋出異常。
最佳實(shí)踐總結(jié)??
- ??安全優(yōu)先??:
- 使用??列表??傳參(如 ["ls", "-l"]),避免 shell=True除非必要
- ??輸出處理??:
- 需捕獲輸出時(shí),用 capture_output=True+ text=True簡(jiǎn)化代碼。
- ??異常管理??:
- 關(guān)鍵命令添加 check=True+ try/except確保失敗可追溯
- ??跨平臺(tái)注意??:
- Windows 部分命令(如 dir)需 shell=True
- ??性能優(yōu)化??:
- 避免頻繁調(diào)用高開銷命令(如反復(fù)啟動(dòng) Shell)
subprocess.Popen
1 、subprocess.Popen能夠提供更大的靈活性。
subprocess.run 可以看成是 subprocess.Popen 一個(gè)簡(jiǎn)化抽象。
2 、subprocess.Popen的使用與注意
1.默認(rèn)情況下, subprocess.Popen 不會(huì)中暫停 Python 程序本身的運(yùn)行(異步)
2.但是如果你非得同前面兩種方式一樣,同步運(yùn)行,你可以加上 .wait() 方法。
3.當(dāng)我們?nèi)匀惶幵诋惒降臓顩r,通過(guò) poll() 來(lái)輪詢,知道shell 命令是否運(yùn)行結(jié)束與否?當(dāng)放回結(jié)果為 None,則表示程序還在運(yùn)行,否者會(huì)返回一個(gè)狀態(tài)碼。
如果想, 指定輸入?yún)?shù) ,則需要通過(guò) communicate() 方法。
import subprocess useless_cat_call=subprocess.Popen(['cat'],stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE,text=True) output,errors=useless_cat_call.communicate(input="hello") useless_cat_call.wait() print(output) print(errors)
/home/topeet/miniconda3/envs/rknn/bin/python3 /home/topeet/test/python/test.py
hello
到此這篇關(guān)于淺談Python調(diào)用Shell腳本的三種常用方式的文章就介紹到這了,更多相關(guān)Python調(diào)用Shell腳本內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python將CSV和Excel表格數(shù)據(jù)導(dǎo)入到Word表格
在不同格式的文檔之間進(jìn)行數(shù)據(jù)傳輸是非常重要的操作,例如將CSV和Excel表格數(shù)據(jù)導(dǎo)入到Word文檔中,不僅可以實(shí)現(xiàn)數(shù)據(jù)的有效整合與展示,還能極大地提升工作效率和文檔的專業(yè)性,本文將介紹如何使用Python將CSV和Excel表格數(shù)據(jù)導(dǎo)入到Word文檔中并創(chuàng)建表格2024-09-09
Python import自己的模塊報(bào)錯(cuò)問題及解決
這篇文章主要介紹了Python import自己的模塊報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Python文件讀寫操作基礎(chǔ)知識(shí)和實(shí)戰(zhàn)應(yīng)用
本文系統(tǒng)講解了Python文件操作的基礎(chǔ)知識(shí)和實(shí)戰(zhàn)技巧,涵蓋文件打開關(guān)閉、讀寫方法、指針控制、二進(jìn)制處理、異常處理及性能優(yōu)化策略,同時(shí)展望了異步IO、內(nèi)存映射增強(qiáng)等未來(lái)趨勢(shì),需要的朋友可以參考下2025-06-06
python 二維數(shù)組90度旋轉(zhuǎn)的方法
今天小編就為大家分享一篇python 二維數(shù)組90度旋轉(zhuǎn)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python爬蟲庫(kù)BeautifulSoup的介紹與簡(jiǎn)單使用實(shí)例
BeautifulSoup是一個(gè)可以從HTML或XML文件中提取數(shù)據(jù)的Python庫(kù),本文為大家介紹下Python爬蟲庫(kù)BeautifulSoup的介紹與簡(jiǎn)單使用實(shí)例其中包括了,BeautifulSoup解析HTML,BeautifulSoup獲取內(nèi)容,BeautifulSoup節(jié)點(diǎn)操作,BeautifulSoup獲取CSS屬性等實(shí)例2020-01-01

