摘要:主要用來取代一些舊的模塊方法,如等通過子進(jìn)程來執(zhí)行外部指令,并通過管道,獲取子進(jìn)程的執(zhí)行的返回信息。等待子進(jìn)程結(jié)束。
subprocess
subprocess模塊是python從2.4版本開始引入的模塊。主要用來取代 一些舊的模塊方法,如os.system、os.spawn、os.popen、commands.*等subprocess通過子進(jìn)程來執(zhí)行外部指令,并通過input/output/error管道,獲取子進(jìn)程的執(zhí)行的返回信息。
使用方法:
運(yùn)行外部命令:subprocess.call(command)
subprocess的call方法可以用于執(zhí)行一個(gè)外部命令,但該方法不能返回執(zhí)行的結(jié)果,只能返回執(zhí)行的狀態(tài)碼: 成功(0) 或 錯(cuò)誤(非0)
方法一:
subprocess.call(["ls","-l"]) 總用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 68 3月 11 13:39 php-fpm.py 0
方法二:
subprocess.call("ls -l",shell=True) 總用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 68 3月 11 13:39 php-fpm.py 0
上面示例是在終端中運(yùn)行,雖然可以看到運(yùn)行結(jié)果,但實(shí)際取值只是狀態(tài)碼
a = subprocess.call("ls -l",shell=True) 總用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 81 3月 11 13:44 php-fpm.py print(a) 0
錯(cuò)誤處理:subprocess.check_call()
我們說過call執(zhí)行返回一個(gè)狀態(tài)碼,我們可以通過check_call()函數(shù)來檢測(cè)命令的執(zhí)行結(jié)果,如果不成功將返回 subprocess.CalledProcessError 異常
示例:
import subprocess try: subprocess.check_call("sdf",shell=True) except subprocess.CalledProcessError as err: print("Command Error",err)
捕獲輸出結(jié)果:subprocess.check_output()
call()方法啟動(dòng)的進(jìn)程,其標(biāo)準(zhǔn)輸入輸出會(huì)綁定到父進(jìn)程的輸入和輸出。調(diào)用程序無法獲取命令的輸出結(jié)果。但可以通過check_output()方法來捕獲輸出。
示例:
output = subprocess.check_output("ls -l",shell=True) print(output.decode("utf-8"))
import subprocess try: output = subprocess.check_output("lT -l",shell=True,stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: print("Command Error",err) #執(zhí)行結(jié)果 Command Error Command "lT -l" returned non-zero exit status 127
直接處理管道:subprocess.Popen()
函數(shù)call(), check_call() 和 check_output() 都是Popen類的包裝器。直接使用Popen會(huì)對(duì)如何運(yùn)行命令以及如何處理其輸入輸出有更多控制。如通過為stdin, stdout和stderr傳遞不同的參數(shù)。
與進(jìn)程的單向通信:通過Popen()方法調(diào)用命令后執(zhí)行的結(jié)果,可以設(shè)置stdout值為PIPE,再調(diào)用communicate()獲取結(jié)果,返回結(jié)果為tuple. 在python3中結(jié)果為byte類型,要得到str類型需要decode轉(zhuǎn)換一下
輸出結(jié)果(讀)
# 直接執(zhí)行命令輸出到屏幕 >>> subprocess.Popen("ls -l",shell=True)總用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 76 3月 11 13:59 php-fpm.py # 不輸出到屏幕,輸出到變量 >>> proc = subprocess.Popen(["echo",""Stdout""],stdout=subprocess.PIPE) # communicate返回標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)出錯(cuò)信息 >>> stdout_value = proc.communicate() >>> stdout_value (b""Stdout" ", None) >>> proc = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE) >>> stdout_value = proc.communicate() >>> stdout_value (b"xe6x80xbbxe7x94xa8xe9x87x8f 48 drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 10 14:57 Desktop drwxr-xr-x 6 liangml liangml 4096 3xe6x9cx88 4 22:00 Documents drwxr-xr-x 2 liangml liangml 4096 3xe6x9cx88 8 18:32 Downloads drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 3 11:10 GitBook drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 17:52 Music drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 17:48 Pictures drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 26 18:29 PycharmProjects drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 18:01 Steam drwxr-xr-x 10 liangml liangml 4096 2xe6x9cx88 27 11:21 svn drwxr-xr-x 2 liangml liangml 4096 2xe6x9cx88 22 17:48 Templates drwxr-xr-x 2 liangml liangml 4096 2xe6x9cx88 22 17:24 Videos drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 7 21:00 vnote_notebooks ", None) # 結(jié)果輸出到文件 >>> file_handle = open("/home/liangml/t.log","w+") >>> subprocess.Popen("ls -l",shell=True,stdout=file_handle) >>> subprocess.call("ls -l",shell=True) 總用量 52 -rw-r--r-- 1 liangml liangml 779 3月 11 14:14 t.log vnote_notebooks
與進(jìn)程的雙向通信
proc = subprocess.Popen("cat", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) msg = "hello world".encode("utf-8") # 寫入到輸入管道 proc.stdin.write(msg) 11 # 輸入結(jié)果 stdout_value = proc.communicate() stdout_value (b"hello world", None) # 輸出結(jié)果 # 在需要進(jìn)行相互交互的輸入輸出過程也可以使用shtin來實(shí)現(xiàn) # 以下實(shí)現(xiàn)打開python3的終端,執(zhí)行一個(gè)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) b"helloworld " print(err_value) b""
Popen.communicate()方法用于和子進(jìn)程交互:發(fā)送數(shù)據(jù)到stdin,并從stdout和stderr讀數(shù)據(jù),直到收到EOF。等待子進(jìn)程結(jié)束。
捕獲錯(cuò)誤輸出
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_value b"" print(err_value.decode("utf-8")) File "", line 1 print "helloworld" ^ SyntaxError: Missing parentheses in call to "print"
Popen其他方法
Popen.pid 查看子進(jìn)程ID
Popen.returncode 獲取子進(jìn)程狀態(tài)碼,0表示子進(jìn)程結(jié)束,None未結(jié)束
在使用Popen調(diào)用系統(tǒng)命令式,建議使用communicate與stdin進(jìn)行交互并獲取輸出(stdout),這樣能保證子進(jìn)程正常退出而避免出現(xiàn)僵尸進(jìn)程:
示例:
proc = subprocess.Popen("ls -l", shell=True, stdout=subprocess.PIPE) # 當(dāng)前子進(jìn)程ID proc.pid 5919 # 返回狀態(tài)None,進(jìn)程未結(jié)束 print(proc.returncode) None # 通過communicate提交后 out_value = proc.communicate() proc.pid 5919 # 返回狀態(tài)為0,子進(jìn)程自動(dòng)結(jié)束 print(proc.returncode) 0
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/44602.html
摘要:?jiǎn)栴}如何執(zhí)行外部命令,如解決方案使用庫(kù)在之前,使用函數(shù)在及之后,使用函數(shù)討論命令的執(zhí)行默認(rèn)不需要環(huán)境,所以當(dāng)你使用作為參數(shù)時(shí),需要將置位,否則會(huì)報(bào)錯(cuò)誤通常來說對(duì)于執(zhí)行系統(tǒng)命令,我們會(huì)想到,但在官方文檔中已經(jīng)建議了使 問題 如何執(zhí)行外部命令,如ls -l 解決方案 使用subprocess庫(kù) 在Python 3.5之前,使用subprocess.call()函數(shù) >>> import s...
摘要:以前我一直用處理一些系統(tǒng)管理任務(wù)因?yàn)槲艺J(rèn)為那是運(yùn)行命令最簡(jiǎn)單的方式我們能從官方文檔里讀到應(yīng)該用模塊來運(yùn)行系統(tǒng)命令模塊允許我們創(chuàng)建子進(jìn)程連接他們的輸入輸出錯(cuò)誤管道,還有獲得返回值。模塊打算來替代幾個(gè)過時(shí)的模塊和函數(shù),比如命令。 以前我一直用os.system()處理一些系統(tǒng)管理任務(wù),因?yàn)槲艺J(rèn)為那是運(yùn)行l(wèi)inux命令最簡(jiǎn)單的方式.我們能從Python官方文檔里讀到應(yīng)該用subprocess...
摘要:原因很簡(jiǎn)單,因?yàn)橹械拇淼木褪钱?dāng)前執(zhí)行的模塊名。缺點(diǎn)就是主程序會(huì)受待執(zhí)行程序的影響,會(huì)出現(xiàn)待執(zhí)行程序中拋異常或主動(dòng)退出會(huì)導(dǎo)致主程序也退出的尷尬問題??偨Y(jié)來說就是,一個(gè)是在子進(jìn)程中執(zhí)行代碼,一個(gè)是在當(dāng)前進(jìn)程中執(zhí)行代碼。 showImg(https://segmentfault.com/img/remote/1460000018607395?w=502&h=318); 相信剛接觸Pytho...
摘要:?jiǎn)卧卦孢@是整數(shù)這才是元祖也許這兩行,你們當(dāng)時(shí)疑惑過,并且現(xiàn)在也都知道了,當(dāng)然重點(diǎn)并不在這里。。雖然我水平很垃圾,但是我知道匿名函數(shù)有一種執(zhí)行方式叫做自執(zhí)行??窗?,這就是版的匿名函數(shù)自執(zhí)行方法。 單元素元祖: a = (1) # 這是整數(shù)1 a = (1,) # 這才是元祖 也許這兩行,你們當(dāng)時(shí)疑惑過,并且現(xiàn)在也都知道了,當(dāng)然重點(diǎn)并不在這里。。 我無聊的時(shí)候想過,為什么單...
摘要:可以執(zhí)行命令的相關(guān)模塊和函數(shù)有廢棄廢棄廢棄,中被移除以上執(zhí)行命令的相關(guān)的模塊和函數(shù)的功能均在模塊中實(shí)現(xiàn),并提供了更豐富的功能。所以不能將設(shè)置為同時(shí)重定向子進(jìn)程的標(biāo)準(zhǔn)輸入輸出與錯(cuò)誤。同上用于設(shè)置子進(jìn)程的當(dāng)前目錄用于指定子進(jìn)程的環(huán)境變量。 可以執(zhí)行shell命令的相關(guān)模塊和函數(shù)有: os.system os.spawn os.popen --廢棄 popen --廢棄...
閱讀 2039·2023-04-25 14:50
閱讀 2919·2021-11-17 09:33
閱讀 2622·2019-08-30 13:07
閱讀 2848·2019-08-29 16:57
閱讀 915·2019-08-29 15:26
閱讀 3557·2019-08-29 13:08
閱讀 2002·2019-08-29 12:32
閱讀 3394·2019-08-26 13:57