python利用subprocess執行交互命令

来源:https://www.cnblogs.com/xxpythonxx/archive/2023/07/22/17573599.html
-Advertisement-
Play Games

Redis是用C語言開發的一個開源的高性能鍵值對(key-value)資料庫,官方提供測試數據,50個併發執行100000個請求,讀的速度是110000次/s,寫的速度是81000次/s ,且Redis通過提供多種鍵值數據類型來適應不同場景下的存儲需求,目前為止Redis支持的鍵值數據類型如下: > ...


已經知道,os.system可以方便的利用python代碼執行一些像ping、ipconfig之類的系統命令,但卻只能得到命令執行是否成功,不能獲得命令成功執行後的結果,像下麵這樣:

>>> s = os.system("ping www.baidu.com")

正在 Ping www.a.shifen.com [220.181.38.150] 具有 32 位元組的數據:
來自 220.181.38.150 的回覆: 位元組=32 時間=18ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=19ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=23ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=22ms TTL=52

220.181.38.150 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
    最短 = 18ms,最長 = 23ms,平均 = 20ms
>>> s
0
>>> type(s)
<class 'int'>
>>>

在上面的代碼中,利用os.system執行“ping www.baidu.com”並把結果賦值給s,但在下麵可以看到,s的內容是int類型的0(表示命令執行成功),並不是命令的執行結果。如果只是需要判斷命令是否執行成功,那完全可以使用這種方法,但如果想要獲取命令執行的結果呢?可以使用subprocess這個模塊。

一:subprocess的作用

subprocess模塊主要用於創建子進程,並連接它們的輸入、輸出和錯誤管道,獲取它們的返回狀態。通俗地說就是通過這個模塊,你可以在Python的代碼里執行操作系統級別的命令,比如“ipconfig”、“du -sh”等等。subprocess模塊替代了一些老的模塊和函數,比如:

os.system
os.spawn*

subprocess過去版本中的call(),check_call()和check_output()已經被run()方法取代了。run()方法為3.5版本新增。大多數情況下,推薦使用run()方法調用子進程,執行操作系統命令。在更高級的使用場景,你還可以使用Popen介面。其實run()方法在底層調用的就是Popen介面。

二:subprocess的run方法

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, encoding=None, errors=None)

功能:執行args參數所表示的命令,等待命令結束,並返回一個CompletedProcess類型對象。

下麵是run參數的作用:

  • args:表示要執行的命令。必須是一個字元串,字元串參數列表。

  • stdin、stdout和stderr:子進程的標準輸入、輸出和錯誤。其值可以是subprocess.PIPE、subprocess.DEVNULL、一個已經存在的文件描述符、已經打開的文件對象或者None。subprocess.PIPE表示為子進程創建新的管道。subprocess.DEVNULL表示使用os.devnull。預設使用的是None,表示什麼都不做。另外,stderr可以合併到stdout里一起輸出。

  • timeout:設置命令超時時間。如果命令執行時間超時,子進程將被殺死,並彈出TimeoutExpired異常。

  • check:如果該參數設置為True,並且進程退出狀態碼不是0,則彈出CalledProcessError異常。

  • encoding:如果指定了該參數,則stdin、stdout和stderr可以接收字元串數據,並以該編碼方式編碼。否則只接收bytes類型的數據。

  • shell:如果該參數為True,將通過操作系統的shell執行指定的命令,如果執行命令時遇見許可權不足的境況,可以將此參數設置為True

註意,run()方法返回的不是我們想要的執行結果或相關信息,而是一個CompletedProcess類型對象。

>>> r = subprocess.run("ping www.baidu.com")

正在 Ping www.a.shifen.com [220.181.38.150] 具有 32 位元組的數據:
來自 220.181.38.150 的回覆: 位元組=32 時間=17ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=17ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=19ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=18ms TTL=52

220.181.38.150 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
    最短 = 17ms,最長 = 19ms,平均 = 17ms
>>> type(r)
<class 'subprocess.CompletedProcess'>
>>> r
CompletedProcess(args='ping www.baidu.com', returncode=0)
>>>

可以看到,run方法的執行結果是一個CompletedProcess類型對象。

下麵是CompletedProcess類型對象的一些屬性:

args 啟動進程的參數,通常是個列表或字元串。

returncode 進程結束狀態返回碼。0表示成功狀態。

stdout 獲取子進程的stdout。通常為bytes類型序列,None表示沒有捕獲值。如果你在調用run()方法時,設置了參數stderr=subprocess.STDOUT,則錯誤信息會和stdout一起輸出,此時stderr的值是None。

stderr() 獲取子進程的錯誤信息。通常為bytes類型序列,None表示沒有捕獲值。

check_returncode() 用於檢查返回碼。如果返回狀態碼不為零,彈出CalledProcessError異常。

獲取狀態碼:

r = subprocess.run("ping www.baidu.com")

正在 Ping www.a.shifen.com [220.181.38.150] 具有 32 位元組的數據:
來自 220.181.38.150 的回覆: 位元組=32 時間=35ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=29ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=16ms TTL=52
來自 220.181.38.150 的回覆: 位元組=32 時間=18ms TTL=52

220.181.38.150 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
    最短 = 16ms,最長 = 35ms,平均 = 24ms>>> r.returncode
0

獲取命令執行後的內容:

run()方法返回的是一個CompletedProcess類型對象,不能直接獲取我們通常想要的結果。要獲取命令執行的結果或者信息,在調用run()方法的時候,請指定stdout=subprocess.PIPE。

>>> ret = subprocess.run('dir', shell=True, stdout=subprocess.PIPE)
>>> ret
CompletedProcess(args='dir', returncode=0, stdout=b' \xc7\xfd\xb6\xaf\xc6\xf7 C \xd6\xd0\xb5\xc4\xbe\xed\xca\xc7 Windows 10\r\n \xbe\xed\xb5\xc4\xd0\xf2\xc1\xd0\xba\xc5\xca\xc7 02DE-BFF0\r\n\r\n C:\\Users\\lwy \xb5\xc4\xc4\xbf\xc2\xbc\r\n\r\n2019/12/31  10:29    <DIR>          .\r\n2019/12/31  10:29    <DIR>          ..\r\n2019/10/16  10:27    <DIR>          .3T\r\n2019/09/23  20:31    <DIR>          .anaconda\r\n2019/10/07  13:14    <DIR>          .android\r\n2019/07/23  09:54    <DIR>          .astropy\r\n2019/12/28  19:01             4,807 .bash_history\r\n2019/09/26  18:19    <DIR>          .conda\r\n2019/09/26  18:19               151 .condarc\r\n2019/10/07  10:18    <DIR>          .config\r\n2019/11/02  11:50             1,126 .dbshell\r\n2019/07/31  16:49               181 .gitconfig\r\n2019/07/22  20:31    <DIR>          .ipython\r\n2019/09/23  16:15    <DIR>          .keras\r\n2019/11/06  21:47    <DIR>          .matplotlib\r\n2019/08/01  09:36                37 .minttyrc\r\n2019/10/06  20:53    <DIR>          .mitmproxy\r\n2019/10/01  15:20                 0 .mongorc.js\r\n2019/08/30  15:19    <DIR>          .oracle_jre_usage\r\n2019/07/21  23:57    <DIR>          .PyCharm2019.1\r\n2019/12/10  17:04                25 .python_history\r\n2019/07/31  16:04    <DIR>          .rdm\r\n2019/07/31  16:38                35 .rediscli_history\r\n2019/07/22  20:31    <DIR>          .spyder-py3\r\n2019/09/17  17:51             5,339 .viminfo\r\n2019/12/12  13:21    <DIR>          3D Objects\r\n2019/12/12  13:21    <DIR>          Contacts\r\n2019/12/31  13:41    <DIR>          Desktop\r\n2019/12/18  15:47    <DIR>          Documents\r\n2019/12/30  16:34    <DIR>          Downloads\r\n2019/12/12  13:21    <DIR>          Favorites\r\n2019/10/15  16:36    <DIR>          Funshion\r\n2019/12/12  13:21    <DIR>          Links\r\n2019/12/12  13:21    <DIR>          Music\r\n2019/07/21  23:58    <DIR>          OneDrive\r\n2019/12/12  13:21    <DIR>          Pictures\r\n2019/12/12  13:21    <DIR>          Saved Games\r\n2019/12/12  13:21    <DIR>          Searches\r\n2019/12/31  10:27    <DIR>          test22\r\n2019/12/12  13:21    <DIR>          Videos\r\n               9 \xb8\xf6\xce\xc4\xbc\xfe         11,701 \xd7\xd6\xbd\xda\r\n              31 \xb8\xf6\xc4\xbf\xc2\xbc 51,676,090,368 \xbf\xc9\xd3\xc3\xd7\xd6\xbd\xda\r\n')
>>> type(ret)
<class 'subprocess.CompletedProcess'>
>>>

可以看到,這時候返回的內容就是命令的執行結果了,是一個CompletedProcess的類型,也可以通過指定編碼使返回對象是一個字元串類型。

>>> ret = subprocess.run('dir', shell=True, stdout=subprocess.PIPE).stdout.decode("gbk")
>>> ret
' 驅動器 C 中的捲是 Windows 10\r\n 捲的序列號是 02DE-BFF0\r\n\r\n C:\\Users\\lwy 的目錄\r\n\r\n2019/12/31  10:29    <DIR>          .\r\n2019/12/31  10:29    <DIR>          ..\r\n2019/10/16  10:27    <DIR>          .3T\r\n2019/09/23  20:31    <DIR>          .anaconda\r\n2019/10/07  13:14    <DIR>          .android\r\n2019/07/23  09:54    <DIR>          .astropy\r\n2019/12/28  19:01             4,807 .bash_history\r\n2019/09/26  18:19    <DIR>          .conda\r\n2019/09/26  18:19               151 .condarc\r\n2019/10/07  10:18    <DIR>          .config\r\n2019/11/02  11:50             1,126 .dbshell\r\n2019/07/31  16:49               181 .gitconfig\r\n2019/07/22  20:31    <DIR>          .ipython\r\n2019/09/23  16:15    <DIR>          .keras\r\n2019/11/06  21:47    <DIR>          .matplotlib\r\n2019/08/01  09:36                37 .minttyrc\r\n2019/10/06  20:53    <DIR>          .mitmproxy\r\n2019/10/01  15:20                 0 .mongorc.js\r\n2019/08/30  15:19    <DIR>          .oracle_jre_usage\r\n2019/07/21  23:57    <DIR>          .PyCharm2019.1\r\n2019/12/10  17:04                25 .python_history\r\n2019/07/31  16:04    <DIR>          .rdm\r\n2019/07/31  16:38                35 .rediscli_history\r\n2019/07/22  20:31    <DIR>          .spyder-py3\r\n2019/09/17  17:51             5,339 .viminfo\r\n2019/12/12  13:21    <DIR>          3D Objects\r\n2019/12/12  13:21    <DIR>          Contacts\r\n2019/12/31  13:41    <DIR>          Desktop\r\n2019/12/18  15:47    <DIR>          Documents\r\n2019/12/30  16:34    <DIR>          Downloads\r\n2019/12/12  13:21    <DIR>          Favorites\r\n2019/10/15  16:36    <DIR>          Funshion\r\n2019/12/12  13:21    <DIR>          Links\r\n2019/12/12  13:21    <DIR>          Music\r\n2019/07/21  23:58    <DIR>          OneDrive\r\n2019/12/12  13:21    <DIR>          Pictures\r\n2019/12/12  13:21    <DIR>          Saved Games\r\n2019/12/12  13:21    <DIR>          Searches\r\n2019/12/31  10:27    <DIR>          test22\r\n2019/12/12  13:21    <DIR>          Videos\r\n               9 個文件         11,701 位元組\r\n              31 個目錄 51,681,050,624 可用位元組\r\n'
>>> type(ret)
<class 'str'>
>>>

三:subprocess的Popen方法

並不是所有的操作系統命令都像‘dir’或者‘ipconfig’那樣單純地返回執行結果,還有很多像‘python’這種互動式的命令,你要輸入點什麼,然後它返回執行的結果。subprocess中的Popen方法,可以執行一些交互性的命令。run方法也可以進行一些輸入,不過很不方便,也不是以代碼的形式驅動的,想要瞭解的同學可以看下文末大佬的原文。

Popen的用法和參數與run()方法基本類同,但是它的返回值是一個Popen對象,而不是CompletedProcess對象。

>>> r = subprocess.Popen("dir", shell=True)>>> type(r)
<class 'subprocess.Popen'>
>>> r
<subprocess.Popen object at 0x000001921134EC48>
>>>

要‘python’命令功能,可以按下麵的例子操作:

import subprocess

s = subprocess.Popen("python", stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
s.stdin.write(b"import os\n")
s.stdin.write(b"print(os.environ)")
s.stdin.close()

out = s.stdout.read().decode("GBK")
s.stdout.close()
print(out)

另外,也可以把需要執行的後續命令卸載一個txt文件里,打開這個文件並賦值給stdin這個參數:

f = open("111.txt", "r+")

s = subprocess.Popen("python",stdout=subprocess.PIPE, stdin=f, shell=True)

out = s.stdout.read().decode("utf-8")
s.stdout.close()
print(out) 

111.txt文件中的內容是:

 import os
 print(os.getcwd())

註意:每行代碼後面要加換行。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 背景 最近聽音樂的時候,看到各種動效,突然好奇這些音頻數據是如何獲取並展示出來的,於是花了幾天功夫去研究相關的內容,這裡只是給大家一些代碼實例,具體要看懂、看明白,還是建議大家大家結合相關API文檔來閱讀這篇文章。 參考資料地址:Web ...
  • 第1代圖片驗證碼 - 字母數字型 第2代滑動驗證碼 - 圖片截取型 第3代驗證碼 - 選圖型 vercode.js 結合了上面的情況下新研發的一種驗證碼。 驗證碼類型 驗證碼描述 操作性 安全性 描述 字母數字型圖片驗證碼 這是一種通過後臺隨機碼生成圖片的驗證碼。伺服器會在隨機碼生成時保存隨機碼。 ...
  • Java三大特征:封裝,繼承和多態成員變數:靜態成員變數(static)和實例成員變 訪問方法:類名.靜態成員變數;對象.實例成員變數;對象.靜態成員變數;(第三個不推薦) 套話:靜態的都可以訪問,實例的只能實例的訪問 繼承中子類不能繼承父類的構造方法,eg:父類:public People(int ...
  • # 1.網站的入口--路由和視圖 URL是網站Web服務的入口。用戶在瀏覽器輸入URL發出請求後,django會根據路由系統,運行對應的視圖函數,然後返回信息到瀏覽器中。 ## 1.1 認識路由 創建項目時,會自動生成urls.文件,文件中定義了項目的路由信息,成為項目的路由解析入口。在自建的應用中 ...
  • 操作系統 : debian 11 (bullseye,docker)、Windows10_x64 FreeSWITCH版本 :1.10.9 Docker版本:23.0.6 Python 版本 : 3.9.2 日常工作中,有時候會遇到g729編碼的相關內容,但FreeSWITCH預設是不支持g729編 ...
  • # JVM運行時數據區之堆空間 ## 1.核心概述 一個JVM實例只存在一個堆記憶體,堆也是Java記憶體管理的核心區域。堆區在**JVM 啟動的時候即被創建**,其空間大小也就確定了,是**JVM管理的最大一塊記憶體空間**。 《Java虛擬機規範》中對Java堆的描述是:所有的對象實例以及數組都應當在 ...
  • 一個從多個父類繼承過來的子類,可以訪問所有父類的功能。並不推薦使用。 多重繼承最簡單有用的形式是mixin。假設在之前Contact類增加一個功能,允許給self.email發送一封郵件。 ```python class ContactList(list): def search(self, nam ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...