(1) os.system
? 這個(gè)方法是直接調(diào)用標(biāo)準(zhǔn)C的system() 函數(shù),僅僅在一個(gè)子終端運(yùn)行系統(tǒng)命令,而不能獲取命令執(zhí)行后的返回信息。
? import os
os.system('cat /proc/cupinfo')
(2) os.popen
? 該方法不但執(zhí)行命令還返回執(zhí)行后的信息對象,是通過一個(gè)管道文件將結(jié)果返回。
? output = os.popen('cat /proc/cpuinfo')
? print output.read()
(3)使用模塊commands模塊
? ? import commands
? (status, output) = commands.getstatusoutput('cat /proc/cpuinfo')
? print status,output
注意1:在類unix的系統(tǒng)下使用此方法返回的返回值(status)與腳本或命令執(zhí)行之后的返回值不等,這是因?yàn)檎{(diào)用了os.wait()的緣故,
? ? ? ? ? 具體原因就得去了解下系統(tǒng)wait()的實(shí)現(xiàn)了。需要正確的返回值(status),只需要對返回值進(jìn)行右移8位操作就可以了。
注意2:當(dāng)執(zhí)行命令的參數(shù)或者返回中包含了中文文字,那么建議使用subprocess。
(4) 使用模塊subprocess
Subprocess是一個(gè)功能強(qiáng)大的子進(jìn)程管理模塊,是替換os.system ,os.spawn* 等方法的一個(gè)模塊。subprocess模塊目的是fork一個(gè)新的進(jìn)程并與之通信,最常用是定義類Popen,使用Popen可以創(chuàng)建進(jìn)程,并與進(jìn)程進(jìn)行復(fù)雜的交互。其函數(shù)原型為:
Class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? stderr=None, preexec_fn=None,? close_fds=True, shell=False,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cwd=None, env=None, universal_newlines=False, startupinfo=None,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
args:這個(gè)參數(shù)必須是字符串或者是一個(gè)由字符串成員的列表。其中如果是一個(gè)字符串列表的話,那第一個(gè)成員為要運(yùn)行的程序的路徑以及程序名稱;從第二個(gè)成員開始到最后一個(gè)成員為運(yùn)行這個(gè)程序需要輸入的參數(shù)。
executable:指定要運(yùn)行的程序,這個(gè)一般很少用到,因?yàn)橐付ㄟ\(yùn)行的程序在args中已經(jīng)指定了。stdin,stdout ,stderr:分別代表程序的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤處理??梢赃x擇的值有PIPE,已經(jīng)存在的打開的文件對象和NONE。若stdout是文件對象的話,要確保文件對象是處于打開狀態(tài)。
shell:默認(rèn)是False。shell參數(shù)根據(jù)要執(zhí)行的命令情況來定,如果將參數(shù)shell設(shè)為True,executable將指定程序使用的shell。在windows平臺下,默認(rèn)的shell由COMSPEC環(huán)境變量來指定。
bufsize:指定緩沖。0 無緩沖,1 行緩沖,其他 緩沖區(qū)大小,負(fù)值 系統(tǒng)緩沖
cwd:用于設(shè)置子進(jìn)程的當(dāng)前目錄
stdin, stdout, stderr:分別表示程序的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤輸出,可以是 subprocess.PIPE 或 其他程序、文件。
env:用于指定子進(jìn)程的環(huán)境變量。如果env = None,子進(jìn)程的環(huán)境變量將從父進(jìn)程中繼承。
universal_newlines:不同系統(tǒng)的換行符不同,True 即使用 \n
preexec_fn:只在Unix平臺下有效,用于指定一個(gè)可執(zhí)行對象(callable object),它將在子進(jìn)程運(yùn)行之前被調(diào)用。
用法: child = subprocess.Popen(["cmd","arg1"...])
subprocess.Popen類的實(shí)例可調(diào)用的方法
Popen.poll() 用于檢查子進(jìn)程(命令)是否已經(jīng)執(zhí)行結(jié)束,沒結(jié)束返回None,結(jié)束后返回狀態(tài)碼。
Popen.wait(timeout=None) 等待子進(jìn)程結(jié)束,并返回狀態(tài)碼;如果在timeout指定的秒數(shù)之后進(jìn)程還沒有結(jié)束,將會拋出一個(gè)TimeoutExpired異常。
Popen.communicate(input=None, timeout=None) 該方法可用來與進(jìn)程進(jìn)行交互,比如發(fā)送數(shù)據(jù)到stdin,從stdout和stderr讀取數(shù)據(jù),直到到達(dá)文件末尾。
Popen.send_signal(signal) 發(fā)送指定的信號給這個(gè)子進(jìn)程。
Popen.terminate() 停止該子進(jìn)程。
Popen.kill() 殺死該子進(jìn)程。
其他函數(shù)
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)
subprocess.run() Python 3.5中新增的函數(shù)。執(zhí)行指定的命令,等待命令執(zhí)行完成后返回一個(gè)包含執(zhí)行結(jié)果的CompletedProcess類的實(shí)例。
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
subprocess.call() 執(zhí)行指定的命令,返回命令執(zhí)行狀態(tài),其功能類似于os.system(cmd)。
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
subprocess.check_call() Python 2.5中新增的函數(shù)。 執(zhí)行指定的命令,如果執(zhí)行成功則返回狀態(tài)碼,否則拋出異常。其功能等價(jià)于subprocess.run(..., check=True)。
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)
subprocess.check_output() Python 2.7中新增的的函數(shù)。執(zhí)行指定的命令,如果執(zhí)行狀態(tài)碼為0則返回命令執(zhí)行結(jié)果,否則拋出異常。
subprocess.getstatusoutput(cmd)
subprocess.getstatusoutput(cmd) 執(zhí)行cmd命令,返回一個(gè)元組(命令執(zhí)行狀態(tài), 命令執(zhí)行結(jié)果輸出),其功能類似于commands.getstatusoutput()。
subprocess.getoutput(cmd)
subprocess.getoutput(cmd) 接收字符串格式的命令,執(zhí)行命令并返回執(zhí)行結(jié)果,其功能類似于os.popen(cmd).read()和commands.getoutput(cmd)。
總結(jié)
subprocess是用來替代os.system等函數(shù)的,當(dāng)subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()這些高級函數(shù)無法滿足需求時(shí),我們可以使用subprocess.Popen類來實(shí)現(xiàn)我們需要的復(fù)雜功能。
有豐富的參數(shù)可以進(jìn)行配置,可供我們自定義的選項(xiàng)多,靈活性高。之前我使用os.system的時(shí)候遇到文件描述符被子進(jìn)程繼承的問題,后來通過close_fds = False 這個(gè)參數(shù)來解決的。