subprocess *
為了方便你理解,我們用一個很簡單的一段代碼來說明:
可以看見我們利用Popen實例化了一個p,創建了子程序cmd.exe,然后我們給他的的Stdin(標準輸入流)Stdout(標準輸出流);
同時使用了subprocess.PIPE 作為參數,這個是一個特殊值,用于表明這些通道要開放。(在Python3.5,加入了run()方法來進行更好的操作)
然后我們繼續
這些信息是不是很眼熟?這都是cmd的標準輸出!
然后就會輸出這些:
我們剛剛所寫入的信息"echo Hellwworlds "已經被寫入了,看起來確實成功了!
注意一下我們使用了 p.stdin.flush() 來對輸入緩存區進行刷新,輸出的信息也需要一個 " ",至少在 Windows 系統下必須這樣做,否則只刷新(p.stdin.flush)的話是無效的;
我們成功的創建了子程序 cmd.exe,并且寫入"echo Hellwworlds " ,然后cmd獲取了并且執行,于是返回 Hellwworlds,這就是一次很簡單的讀寫交互!
既然我們已經可以簡單的讀寫了,那么加點for和threading 吧,味道也許更佳喔~
#run.py from subprocess import * import threading import time p =Popen('cmd.exe',shell=True,stdin=PIPE,stdout=PIPE) def run(): global p while True: line = p.stdout.readline() if not line: #空則跳出 break print(">>>>>>",line.decode("GBK")) print("look up!!! EXIT ===") #跳出 w =threading.Thread(target=run) p.stdin.write("echo HELLW_WORLD! ".encode("GBK")) p.stdin.flush() time.sleep(1) #延遲是因為等待一下線程就緒 p.stdin.write("exit ".encode("GBK")) p.stdin.flush() w.start()
很好很好,猜猜輸出什么?
有很多換行的原因是cmd返回的結果有換行,然后print輸出會加一個換行,所以就換了兩行,你可以考慮使用 sys.stdout.write 來輸出,這樣就沒有附加的換行了
這樣的話,你可以制作一個基礎的讀寫了,那么我們開始封裝吧。
不廢話了,直接上代碼,如果你真的想學會的話,還請認真自己讀讀代碼。
110行
我們實現了將所有的過程集中在一個類里面,并且可以定義三個參數,退出反饋函數,就緒反饋函數和輸出反饋函數。
# -*- coding:utf-8 -*- import subprocess import sys import threading class LoopException(Exception): """循環異常自定義異常,此異常并不代表循環每一次都是非正常退出的""" def __init__(self,msg="LoopException"): self._msg=msg def __str__(self): return self._msg class SwPipe(): """ 與任意子進程通信管道類,可以進行管道交互通信 """ def __init__(self,commande,func,exitfunc,readyfunc=None, shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,code="GBK"): """ commande 命令 func 正確
輸出:
你可以看見,我們的指令都順序的執行了。當然了這里面還有OS的功勞。
那么你的可擴展的Pipe類應該已經構建完畢了吧?
A: 我之所以要在這種代碼前面加入行數的原因就是為了防止你復制;因為你可能永遠不會明白這里究竟發生了什么,而是只懂得了使用。
順便一提:
最好去參考一下官方的文檔,已經講得非常詳細了。subprocess.Popen.communicate 或許更適合你,看你是要進行什么事情。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com