subprocess.wait()與subprocess.communicate()使用問題
subprocess就是開啟一個子進程,自己去執(zhí)行命令士败,這個子進程的狀態(tài)肯定得收集莺匠,這時候就需要調(diào)用wait或者communicate了钙勃,手冊上面也注明了這兩個方法的特點:在數(shù)據(jù)超過PIPE的緩存時旭愧,wait會阻塞進程;communicate會把所有的數(shù)據(jù)都讀取到內(nèi)存中
那么現(xiàn)在就有一個問題了慈参,當我shell命令執(zhí)行的結(jié)果很大時,我是該用wait還是communicate刮萌?用wait直接就阻塞了驮配,肯定不行,用communicate也不行着茸,如果很大的文件僧凤,數(shù)據(jù)都保存在內(nèi)存,主機直接就卡死了元扔。
解決辦法:數(shù)據(jù)一行一行讀取躯保,讀取完之后wait,這樣既保證了不會阻塞(PIPE中數(shù)據(jù)有進有出澎语,最后空了才wait)途事,又保證了不會占用大量主機內(nèi)存(在內(nèi)存中的數(shù)據(jù)只有一行l(wèi)ine)。
p1=subprocess.Popen(comm1,shell=True,stdout=subprocess.PIPE)
for line in p1.stdout:
pass
p1.wait()
subprocess.Popen():
在一些復雜場景中擅羞,我們需要將一個進程的執(zhí)行輸出作為另一個進程的輸入尸变。在另一些場景中,我們需要先進入到某個輸入環(huán)境减俏,然后再執(zhí)行一系列的指令等召烂。這個時候我們就需要使用到suprocess的Popen()方法。該方法有以下參數(shù):
args:shell命令娃承,可以是字符串奏夫,或者序列類型怕篷,如list,tuple。
bufsize:緩沖區(qū)大小酗昼,可不用關心
stdin,stdout,stderr:分別表示程序的標準輸入廊谓,標準輸出及標準錯誤
shell:與上面方法中用法相同
cwd:用于設置子進程的當前目錄
env:用于指定子進程的環(huán)境變量。如果env=None麻削,則默認從父進程繼承環(huán)境變量
universal_newlines:不同系統(tǒng)的的換行符不同蒸痹,當該參數(shù)設定為true時,則表示使用\n作為換行符
例如:
a = subprocess.Popen('mkdir subprocesstest',shell=True,cwd='/root')
還有:
import subprocess
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()