一.簡介
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)
備注:更多詳細關于subprocess點選這裡