subprocess模塊提供多種方法來實現執行 Linux 的命令,例如subprocess.call()方法,subprocess.check_call()方法,等。這些方法都是對Popen類的封裝,故本文著重講述Popen類的使用。
執行 Shell 命令
可以通過向Popen()傳遞需要執行的命令來創建壹個Popen對象,這樣,便會創建壹個子進程來執行命令。例如:
child = subprocess.Popen(["ping","-c","5","leehao.me"])
1
上面的代碼會創建壹個子進程來執行ping -c 5 leehao.me命令,這個命令采用列表的形式傳遞給Popen()方法。如果我們想直接采用ping -c 5 leehao.me字符串形式,可以添加shell=True來實現:
child = subprocess.Popen("ping -c 5 leehao.me", shell=True)
1
官方文檔指出由於安全原因故不建議使用shell=True,詳細說明可以參考官方文檔的描述。
等待子進程執行
子進程執行命令後,主進程並不會等待子進程執行。為了讓主進程等待子進程執行結束,需要顯示調用Popen.wait()方法。例如:
child = subprocess.Popen(["ping","-c","5","leehao.me"])
child.wait()
print 'parent finish'
1
2
3
這樣,主進程會等待子進程執行ping命令完畢後,才會打印出parent finish的輸出。
獲取執行結果
為了獲取Popen()子進程的輸出,可以使用Popen.communicate()方法,例如:
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd('echo leehao.me; echo www.leehao.me')
1
2
3
4
5
6
輸出:
leehao.me
www.leehao.me
process.communicate()方法可以實現主進程與子進程的通信。主進程可以通過它向子進程發送數據,也可以讀取子進程的輸出的數據。上面的例子中,我們在創建Popen對象時指定stdout=subprocess.PIPE,這樣主進程便可以讀取子進程的輸出。
communicate()方法返回壹個元組:(stdoutdata, stderrdata),process.communicate()[0]即獲取子進程的標準輸出。
需要指出的是,調用communicate()方法後,主進程也會等待子進程執行完畢。
上面的例子中,子進程向標準輸出打印兩個字符串,主進程接收到了這些輸出,並打印出來。