Python的subprocess模組總結

來源:互聯網
上載者:User
subprocess意在替代其他幾個老的模組或者函數,比如:os.system os.spawn* os.popen* popen2.* commands.*
subprocess最簡單的用法就是調用shell命令了,另外也可以調用程式,並且可以通過stdout,stdin和stderr進行互動。

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分別表示程式的標準輸入、輸出、錯誤控制代碼。他們可以是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資訊。

以上全是抄的

在程式中運行其他程式或shell

可以這樣寫

代碼如下:


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)

它會返回一個元組:(stdoutdata, stderrdata)

subprocess還有另一種更簡單方法,效果一樣,它會返回stdout

代碼如下:


>>> s = subprocess.check_output('ls -l', shell=True)
>>> s
'\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'

前者可以實現更多的互動,如stderr和stdin,但是在前面調用Popen的時候要實現定義Popen(stdin=subprocess.PIPE, stderr=subprocess)

給子進程輸入

代碼如下:


import subprocess
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.communicate("vamei")

()不為空白,則寫入subprocess.PIPE,為空白,則從subprocess.PIPE讀取


subprocess.PIPE

代碼如下:


#!/usr/bin/env python
import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print out

實際上是這樣的過程

代碼如下:


child1.stdout-->subprocess.PIPE

child2.stdin<--subprocess.PIPE

child2.stdout-->subprocess.PIPE


要注意的是,communicate()是Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成。

subprocess.PIPE實際上為文字資料流提供一個緩衝區。直到communicate()方法從PIPE中讀取出PIPE中的文本.要注意的是,communicate()是Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.