from subprocess import Popen 能夠看到Popen類的方法shell
從Python 2.4開始,Python引入subprocess模塊來管理子進程,以取代一些舊模塊的方法:如 os.system、os.spawn*、os.popen*、popen2.*、commands.*不但能夠調用外部的命令做爲子進程,並且能夠鏈接到子進程的input/output/error管道,獲取相關的返回信息編程
subprocess.call()
父進程等待子進程完成
返回退出信息(returncode,至關於Linux exit code)windows
subprocess.check_call()
父進程等待子進程完成
返回0
檢查退出信息,若是returncode不爲0,則舉出錯誤subprocess.CalledProcessError,該對象包含有returncode屬性,可用try…except…來檢查緩存
subprocess.check_output()
父進程等待子進程完成
返回子進程向標準輸出的輸出結果
檢查退出信息,若是returncode不爲0,則舉出錯誤subprocess.CalledProcessError,該對象包含有returncode屬性和output屬性,output屬性爲標準輸出的輸出結果,可用try…except…來檢查。markdown
這三個函數的使用方法相相似,下面來以subprocess.call()舉例說明:函數
代碼以下:spa
>>> import subprocess
>>> retcode = subprocess.call(["ls", "-l"])
#和shell中命令ls -a顯示結果同樣
>>> print retcode
0操作系統
將程序名(ls)和所帶的參數(-l)一塊兒放在一個表中傳遞給subprocess.call()code
shell默認爲False,在Linux下,shell=False時, Popen調用os.execvp()執行args指定的程序;shell=True時,若是args是字符串,Popen直接調用系統的Shell來執行args指定的程序,若是args是一個序列,則args的第一項是定義程序命令字符串,其它項是調用系統Shell時的附加參數。對象
上面例子也能夠寫成以下:
複製代碼代碼以下:
>>> retcode = subprocess.call("ls -l",shell=True)
subprocess的主類
複製代碼代碼以下:
subprocess.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)
1)、args能夠是字符串或者序列類型(如:list,元組),用於指定進程的可執行文件及其參數。若是是序列類型,第一個元素一般是可執行文件的路徑。咱們也能夠顯式的使用executeable參數來指定可執行文件的路徑。
2)、bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝(全緩衝)
3)、stdin, stdout, stderr分別表示程序的標準輸入、輸出、錯誤句柄。他們能夠是subprocess.PIPE,文件描述符或文件對象,也能夠設置爲None,表示從父進程繼承。
4)、preexec_fn只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用。
5)、Close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。咱們不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
6)、shell設爲true,程序將經過shell來執行。
7)、cwd用於設置子進程的當前目錄
8)、env是字典類型,用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
Universal_newlines:不一樣操做系統下,文本的換行符是不同的。如:windows下用'/r/n'表示換,而Linux下用'/n'。若是將此參數設置爲True,Python統一把這些換行符看成'/n'來處理。startupinfo與createionflags只在windows下用效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。
9)、startupinfo與createionflags只在windows下有效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。
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信息。
能夠這樣寫
subprocess.Popen('腳本/shell', shell=True)
也能夠這樣
subprocess.call('腳本/shell', shell=True)
二者的區別是前者無阻塞,會和主程序並行運行,後者必須等待命令執行完畢,若是想要前者編程阻塞能夠這樣
s = subprocess.Popen('腳本/shell', shell=True)
s.wait()
>>> s = subprocess.Popen('ls -l', shell=True, stdout=subprocess.PIPE)
>>>s.communicate()
('\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 152\n-rw------- 1 limbo limbo 808 7\xe6\x9c\x88 6 17:46 0000-00-00-welcome-to-jekyll.markdown.erb\ndrwx------ 2 limbo limbo 4096 8\xe6\x9c\x88 15 18:43 arg\ndrwx------ 2 limbo limbo 4096 8\xe6\x9c\x88 7 17:37 argv\ndrwxrwxr-x 2 limbo limbo 4096 9\xe6\x9c\x88 10 15:27 c\ndrwxrwxr-x 3 limbo limbo 4096 9\xe6\x9c\x88 11 14:35 d3\ndrwxrwxr-x 3 limbo limbo 4096 9\xe6\x9n', None)
能夠在Popen()創建子進程的時候改變標準輸入、標準輸出和標準錯誤,並能夠利用subprocess.PIPE將多個子進程的輸入和輸出鏈接在一塊兒,構成管道(pipe),以下2個例子:
>>> import subprocess
>>> child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
>>> print child1.stdout.read(),
#或者child1.communicate()
>>> 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()
subprocess.PIPE實際上爲文本流提供一個緩存區。child1的stdout將文本輸出到緩存區,隨後child2的stdin從該PIPE中將文本讀取走。child2的輸出文本也被存放在PIPE中,直到communicate()方法從PIPE中讀取出PIPE中的文本。
注意:communicate()是Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成