Python模組 - subprocess

來源:互聯網
上載者:User

標籤:world   字串   roc   call   通過   tin   err   command   comm   

subprocess – 建立附加進程 
subprocess模組提供了一種一致的方法來建立和處理附加進程,與標準庫中的其它模組相比,提供了一個更進階的介面。用於替換如下模組: 
os.system() , os.spawnv() , os和popen2模組中的popen()函數,以及 commands().

1. 運行外部命令 
subprocess.call(command) 方法 
subprocess的call方法可以用於執行一個外部命令,但該方法不能返回執行的結果,只能返回執行的狀態代碼: 成功(0) 或 錯誤(非0) 
call()方法中的command可以是一個列表,也可以是一個字串,作為字串時需要用原生的shell來執行:

import subprocess#執行 df -hl 命令#方法1:>>> subprocess.call([‘ls‘,‘-l‘])total 8drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystemdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp0#方法2:>>> subprocess.call("ls -l",shell=True)total 8drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystemdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp

如上執行個體所示,雖然我們能看到執行的結果,但實際擷取的值只是狀態代碼

>>> output = subprocess.call("ls -l",shell=True)total 8drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystemdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp>>> print(output)0

2. 錯誤處理 

subprocess.check_call() 方法 
我們說過call執行返回一個狀態代碼,我們可以通過check_call()函數來檢測命令的執行結果,如果不成功將返回 subprocess.CalledProcessError 異常

>>> try:        subprocess.check_call("ls -t", shell=True)    except subprocess.CalledProcessError as err:        print("Command Error") /bin/sh: lt: command not foundCommand Error

3. 捕獲輸出結果 
subprocess.check_output() 方法

call()方法啟動的進程,其標準輸入輸出會綁定到父進程的輸入和輸出。調用程式無法擷取命令的輸出結果。但可以通過check_output()方法來捕獲輸出。

# 以下測試為python3.4下運行結果>>> output=subprocess.check_output("ls -l",shell=True)>>> outputb‘total 8\ndrwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystem\ndrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp\n‘>>> print(output.decode(‘utf-8‘))total 8drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystemdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp

 

以下例子將chek_output()方法執行命令異常時的錯誤捕獲,而避免輸出到控制台.

try:    output = subprocess.check_output("lT -l", shell=True, stderr=subprocess.STDOUT)except subprocess.CalledProcessError as err:    print("Command Error", err)# 執行結果Command Error Command ‘lT -l‘ returned non-zero exit status 127

 

 

直接處理管道 

subprocess.Popen()方法

函數call(), check_call() 和 check_output() 都是Popen類的封裝器。直接使用Popen會對如何運行命令以及如何處理其輸入輸出有更多控制。如通過為stdin, stdout和stderr傳遞不同的參數。

  1. 與進程的單向通訊 
    通過Popen()方法調用命令後執行的結果,可以設定stdout值為PIPE,再調用communicate()擷取結果 
    返回結果為tuple. 在python3中結果為byte類型,要得到str類型需要decode轉換一下

輸出結果(讀)

# 直接執行命令輸出到螢幕>>> subprocess.Popen("ls -l",shell=True)<subprocess.Popen object at 0x7febd4175198>>>> total 12drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystem-rw-rw-r-- 1 ws ws    8 Feb 25 10:38 testdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp# 不輸出到螢幕,輸出到變數>>> proc = subprocess.Popen([‘echo‘,‘"Stdout"‘],stdout=subprocess.PIPE)# communicate返回標準輸出或標準出錯資訊>>> stdout_value = proc.communicate()>>> stdout_value(b‘"Stdout"\n‘, None)>>> proc = subprocess.Popen([‘ls‘,‘-l‘],stdout=subprocess.PIPE)>>> stdout_value = proc.communicate()>>> stdout_value(b‘total 8\ndrwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystem\ndrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp\n‘, None)>>>>>> print((stdout_value[0]).decode(‘utf-8‘))total 8drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystemdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp#將結果輸出到檔案>>> file_handle = open("/home/ws/t.log",‘w+‘)>>> subprocess.Popen("ls -l",shell=True,stdout=file_handle)t.log:drwxrwxr-x 4 ws ws 4096 Nov 25 13:50 MonitorSystem-rw-rw-r-- 1 ws ws    8 Feb 25 10:38 test-rw-rw-r-- 1 ws ws    0 Feb 25 11:24 t.logdrwxrwxr-x 2 ws ws 4096 Feb 19 10:09 tmp

 

2 與進程的雙向通訊

>>> proc = subprocess.Popen(‘cat‘, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)>>> msg = ‘Hello world‘.encode(‘utf-8‘)# 寫入到輸入管道>>> proc.stdin.write(msg)11>>> stdout_value = proc.communicate()>>> stdout_value(b‘Hello world‘, None)# 在需要進行相互互動的輸入輸出過程也可以使用shtin來實現# 以下實現開啟python3的終端,執行一個print命令>>>proc = subprocess.Popen([‘python3‘],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,)>>>proc.stdin.write(‘print("helloworld")‘.encode(‘utf-8‘))>>>out_value,err_value=proc.communicate()>>>print(out_value)>>> print(out_value)b‘helloworld\n‘>>> print(err_value)b‘‘

 

Popen.communicate()方法用於和子進程互動:發送資料到stdin,並從stdout和stderr讀資料,直到收到EOF。等待子進程結束。

捕獲錯誤輸出

>>> proc = subprocess.Popen([‘python3‘],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,)>>> proc.stdin.write(‘print "helloworld"‘.encode(‘utf-8‘))18>>> out_value,err_value=proc.communicate()>>> out_valueb‘‘>>> print(err_value.decode(‘utf-8‘))  File "<stdin>", line 1    print "helloworld"                     ^SyntaxError: Missing parentheses in call to ‘print‘

 

Popen其它方法
  1. Popen.pid 查看子進程ID
  2. Popen.returncode 擷取子進程狀態代碼,0表示子進程結束,None未結束

    在使用Popen調用系統命令式,建議使用communicate與stdin進行互動並擷取輸出(stdout),這樣能保證子進程正常退出而避免出現殭屍進程。看下面例子

>>> proc = subprocess.Popen(‘ls -l‘, shell=True, stdout=subprocess.PIPE)# 當前子進程ID>>> proc.pid28906# 返回狀態為None,進程未結束>>> print(proc.returncode)None# 通過communicate提交後>>> out_value = proc.communicate()>>> proc.pid28906# 返回狀態為0,子進程自動結束>>> print(proc.returncode)0

 

Python模組 - subprocess

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.