一.簡介
subprocess最早在2.4版本引入。用來生成子進程,並可以通過管道連接他們的輸入/輸出/錯誤,以及獲得他們的返回值。
# subprocess用來替換多個舊模塊和函數 os.system os.spawn* os.popen* popen2.* commands.*
運行python的時候,我們都是在創建並運行一個進程,linux中一個進程可以fork一個子進程,並讓這個子進程exec另外一個程序。在python中,我們通過標准庫中的subprocess包來fork一個子進程,並且運行一個外部的程序。subprocess包中定義有數個創建子進程的函數,這些函數分別以不同的方式創建子進程,所以我們可以根據需要來從中選取一個使用。另外subprocess還提供了一些管理標准流(standard stream)和管道(pipe)的工具,從而在進程間使用文本通信。
二.使用
1. call
執行命令,返回狀態碼,shell = True允許shell命令時字符串形式
subprocess.check_call(["ls", "-l"]) subprocess.check_call("exit 1", shell=True)
2. check_call
執行命令,如果執行狀態碼是0,則返回0,否則拋出異常
subprocess.check_call(["ls", "-l"]) subprocess.check_call("exit 1", shell=True)
3. check_output
執行命令,如果狀態碼是0,則返回執行結果,否則拋出異常
subprocess.check_output(["echo", "Hello World!"]) subprocess.check_output("exit 1", shell=True)
4. subprocess.Popen(...)
用於執行復雜的系統命令
參數:
- args: 可以是字符串或者序列類型(如:list, tuple)。默認的,要執行的程序應該是序列的第一個字段,如果是單個字符串,它的解析依賴於平台。在unix中,如果args是一個字符串,那么這個字符串解釋成被執行程序的名字或路徑,然而,這種情況只能用在不需要參數的程序。
- bufsieze: 指定緩沖。0表示無緩沖,1表示緩沖,任何其他的整數值表示緩沖大小,負數值表示使用系統默認緩沖,通常表示完全緩沖。默認值為0即沒有緩沖。
- stdin, stdout, stderr:分別表示程序的標准輸入,輸出,錯誤句柄
- preexec_fn : 只在unix平台有效,用於指定一個可執行對象,它將在子進程中運行之前被調用
- close_fds : 在windows平台下,如果close_fds被設置為true,則新創建的子進程將不會繼承父進程的輸入,輸出,錯誤管道。所以不能將close_fds設置為true同時重定向子進程的標准輸入,輸出與錯誤。
- shell : 默認值為False, 聲明了是否使用shell來執行程序,如果shell=True,它將args看做一個字符串,而不是一個序列。在unix系統中,且shell=True, shell默認使用/bin/sh。
- cwd : 用於設置子進程的當前目錄。當它不為None時,子程序在執行前,它的當前路徑會被替換成cwd的值。這個路徑並不會被添加到可執行程序的搜索路徑,所以cwd不能是相對路徑。
- env : 用於指定子進程的環境變量。如果env=None,子進程的環境變量將從父進程中繼承。當它不為None時,它是新進程的環境變量的映射。可以用它來代替當前進程的環境。
- universal_newlines : 不同系統的換行符不同, 文件對象stdout和stderr都被以文本文件的方式打開
- startupinfo 與 createionflags只在windows下生效。將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等
執行普通命令:
import subprocess ret1 = subprocess.Popen(["mkdir","t1"]) ret2 = subprocess.Popen("mkdir t2", shell=True)
終端輸入的命令分為兩種:
- 輸入即可得到輸出,如:ifconfig
- 輸入進行某環境,依賴在輸入,如: python
import subprocess obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") out_error_list = obj.communicate() print(out_error_list)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list)