python的subprocess模塊

from  subprocess import Popen 能夠看到Popen類的方法shell

 

Python 2.4開始,Python引入subprocess模塊來管理子進程,以取代一些舊模塊的方法:如 os.systemos.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:指定緩衝。無緩衝,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'。若是將此參數設置爲TruePython統一把這些換行符看成'/n'來處理。startupinfocreateionflags只在windows下用效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。

9)startupinfocreateionflags只在windows下有效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。

Popen實例的方法

1)Popen.poll():用於檢查子進程是否已經結束。設置並返回returncode屬性。

2)Popen.wait():等待子進程結束。設置並返回returncode屬性。

3)Popen.communicate(input=None):與子進程進行交互。向stdin發送數據,或從stdoutstderr中讀取數據。可選參數input指定發送到子進程的參數。Communicate()返回一個元組:(stdoutdata, stderrdata)。注意:若是但願經過進程的stdin向其發送數據,在建立Popen對象的時候,參數stdin必須被設置爲PIPE。一樣,若是但願從stdoutstderr獲取數據,必須將stdoutstderr設置爲PIPE

4)Popen.send_signal(signal):向子進程發送信號。

5)Popen.terminate():中止(stop)子進程。在windows平臺下,該方法將調用Windows API TerminateProcess()來結束子進程。

6)Popen.kill():殺死子進程。

7)Popen.stdin:若是在建立Popen對象是,參數stdin被設置爲PIPEPopen.stdin將返回一個文件對象用於策子進程發送指令。不然返回None

8)Popen.stdout:若是在建立Popen對象是,參數stdout被設置爲PIPEPopen.stdout將返回一個文件對象用於策子進程發送指令。不然返回None

9)Popen.stderr:若是在建立Popen對象是,參數stdout被設置爲PIPEPopen.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實際上爲文本流提供一個緩存區child1stdout將文本輸出到緩存區,隨後child2stdin從該PIPE中將文本讀取走。child2的輸出文本也被存放在PIPE中,直到communicate()方法從PIPE中讀取出PIPE中的文本。
注意:communicate()Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成

相關文章
相關標籤/搜索