天天看點

Python3之subprocess子產品

一.簡介

  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)
      

終端輸入的指令分為兩種:

  1. 輸入即可得到輸出,如:ifconfig
  2. 輸入進行某環境,依賴在輸入,如: 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點選這裡