Python subprocess模塊
運行python的時候,我們都是在創建並運行一個進程。像Linux進程那樣,一個進程可以fork一個子進程,並讓這個子進程exec另外一個程序。在Python中,我們通過標准庫中的subprocess包來fork一個子進程,並運行一個外部的程序。
subprocess包中定義有數個創建子進程的函數,這些函數分別以不同的方式創建子進程,所以我們可以根據需要來從中選取一個使用。另外subprocess還提供了一些管理標准流(standard stream)和管道(pipe)的工具,從而在進程間使用文本通信。
subprocess.call()
父進程等待子進程完成
返回退出信息(returncode,相當於Linux exit code)
eg:
>>> a = subprocess.call(['df','-hT'],shell=False)
>>>
>>> a
0 --程序返回的代碼值
subprocess.check_call(args, *, stdin = None, stdout = None, stderr = None, shell = False)
與call方法類似,不同在於如果命令行執行成功,check_call返回返回碼0,否則拋出subprocess.CalledProcessError
異常。
subprocess.CalledProcessError
異常包括returncode、cmd、output等屬性,其中returncode是子進程的退出碼,cmd是子進程的執行命令,output為None。
subprocess.check_output():
用法與上面兩個方法類似,區別是,如果當返回值為0時,直接返回輸出結果,如果返回值不為0,直接拋出異常
>>> a = subprocess.check_output(['df','-hT'],shell=False)
>>> str(a.rstrip(),'utf-8')
>>>
subprocess.Popen():
class Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
在一些復雜場景中,我們需要將一個進程的執行輸出作為另一個進程的輸入。在另一些場景中,我們需要先進入到某個輸入環境,然后再執行一系列的指令等。這個時候我們就需要使用到suprocess的Popen()方法。該方法有以下參數:
args:shell命令,可以是字符串,或者序列類型,如list,tuple。
bufsize:緩沖區大小,可不用關心
stdin,stdout,stderr:分別表示程序的標准輸入,標准輸出及標准錯誤
shell:與上面方法中用法相同
cwd:用於設置子進程的當前目錄
env:用於指定子進程的環境變量。如果env=None,則默認從父進程繼承環境變量
universal_newlines:不同系統的的換行符不同,當該參數設定為true時,則表示使用\n作為換行符
Popen方法
1、Popen.poll():用於檢查子進程是否已經結束。設置並返回returncode屬性。
2、Popen.wait():等待子進程結束。設置並返回returncode屬性。
3、Popen.communicate(input=None):與子進程進行交互。向stdin發送數據,或從stdout和stderr中讀取數據。可選參數input指定發送到子進程的參數。Communicate()返回一個元組:(stdoutdata, stderrdata)。注意:如果希望通過進程的stdin向其發送數據,在創建Popen對象的時候,參數stdin必須被設置為PIPE。同樣,如果希望從stdout和stderr獲取數據,必須將stdout和stderr設置為PIPE。
4、Popen.send_signal(signal):向子進程發送信號。
5、Popen.terminate():停止(stop)子進程。在windows平台下,該方法將調用Windows API TerminateProcess()來結束子進程。
6、Popen.kill():殺死子進程。
7、Popen.stdin:如果在創建Popen對象是,參數stdin被設置為PIPE,Popen.stdin將返回一個文件對象用於策子進程發送指令。否則返回None。
8、Popen.stdout:如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。否則返回None。
9、Popen.stderr:如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。否則返回None。
10、Popen.pid:獲取子進程的進程ID。
11、Popen.returncode:獲取進程的返回值。如果進程還沒有結束,返回None。
12、subprocess.call(*popenargs, **kwargs):運行命令。該函數將一直等待到子進程運行結束,並返回進程的returncode。文章一開始的例子就演示了call函數。如果子進程不需要進行交互,就可以使用該函數來創建。
13、subprocess.check_call(*popenargs, **kwargs):與subprocess.call(*popenargs, **kwargs)功能一樣,只是如果子進程返回的returncode不為0的話,將觸發CalledProcessError異常。在異常對象中,包括進程的returncode信息。
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()
>>> out
(b'root:x:0:0:root:/root:/bin/bash\n', None)
Popen.communicate()
communicate()函數返回一個tuple(標准輸出和錯誤).
Popen.communicate() 和進程溝通:發送數據到標准輸入.從標准輸出和錯誤讀取數據直到遇到結束符.等待進程結束.
輸入參數應該是一個字符串,以傳遞給子進程,如果沒有數據的話應該是None.
基本上,當你用 communicate()函數的時候意味着你要執行命令了.