一 前言python
使用python執行一些命令或調用第三方工具是比較常見的狀況,實現的方法也不少,如os.system(),os.popen()、subprocess模塊中的函數等等,本文主要介紹一下os.popen(),可能隱藏着你未曾接觸的知識點,同時會結合實例進行說明,便於理解。web
二 語法格式sql
首先咱們看下os.popen的語法格式,以下:數據庫
os.popen(cmd, mode='r', buffering=-1)微信
參數說明:ide
Command --- 調用的命令;函數
mode --- 模式權限能夠是 'r'(默認) 或 'w';工具
bufsize -- 指明瞭文件須要的緩衝大小:0意味着無緩衝;1意味着行緩衝;其它正值表示使用參數大小的緩衝(大概值,以字節爲單位);負的bufsize意味着使用系統的默認值。學習
官方釋義:spa
Open a pipe to or from command cmd. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'.
從命令cmd打開一個管道,返回值是鏈接管道的文件對象,經過該對象能夠進行讀或寫。
三 知識點梳理
1. 返回值是文件對象
注意:返回值是文件對象,既然是文件對象,使用完就應該關閉,對吧?!不信網上搜一下,一大把文章提到這個os.popen都是忘記關閉文件對象的。 因此,推薦的寫法是:
with os.popen(command, "r") as p: r = p.read()
至於with的用法就很少講了,使用它,不須要顯式的寫p.close()。
2. 非阻塞
通俗的講,非阻塞就是os.popen不會等cmd命令執行完畢就繼續下面的代碼了,不信?!看下面代碼實例:
從上面實例可知,os.popen執行打開Uedit32.exe這個工具,但從實際執行結果看,Uedit32.exe還沒打開,就直接進入了下一條語句,打印了「hello 小蟒社區」。在某些應用場景,可能這並非你指望的行爲,那如何讓命令執行完後,再執行下一句呢?
處理方法是使用read()或readlines()對命令的執行結果進行讀操做。
3. 徹底阻塞
上面寫了該函數是非阻塞的,如今怎麼又變成徹底阻塞的呢?感受一頭霧水了吧。本質上os.popen是非阻塞的,爲了實現阻塞的效果,咱們使用read()或readlines()對命令結果進行讀,由此產生了阻塞的效果。可是,若是你的命令執行沒法退出或進入交互模式,這種「讀」將造成徹底阻塞的狀況,表現的像程序卡住了。
看下面代碼實例1:
os.popen執行了ping 127.0.0.1 -t 該命令會一直執行,除非CTRL+C強制退出,於是,執行readlines讀取命令輸出時會形成卡住。
代碼實例2:
使用os.popen執行sqlplus命令對數據庫進行操做的場景,若是sqlplus執行失敗,會進入交互模式,如圖所示,此時使用readlines()讀取執行結果時也會卡死,效果如上圖:
四 總結
os.popen()在大多數場景都是挺好用方便的,可是也有坑!! 具體應用中,須要注意下。
建議:
1. 在須要讀取命令執行結果時,避免在命令沒法退出或進入交互模式的場景應用os.popen;
2. os.popen()沒法知足需求時,能夠考慮subprocess.Popen();
五 其餘資源
關於python學習、分享、交流,筆者開通了微信公衆號【小蟒社區】,感興趣的朋友能夠關注下,歡迎加入,創建屬於咱們本身的小圈子,一塊兒學python。