摘要:主要用來取代一些舊的模塊方法,如等通過子進程來執行外部指令,并通過管道,獲取子進程的執行的返回信息。等待子進程結束。
subprocess
subprocess模塊是python從2.4版本開始引入的模塊。主要用來取代 一些舊的模塊方法,如os.system、os.spawn、os.popen、commands.*等subprocess通過子進程來執行外部指令,并通過input/output/error管道,獲取子進程的執行的返回信息。
使用方法:
運行外部命令:subprocess.call(command)
subprocess的call方法可以用于執行一個外部命令,但該方法不能返回執行的結果,只能返回執行的狀態碼: 成功(0) 或 錯誤(非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
上面示例是在終端中運行,雖然可以看到運行結果,但實際取值只是狀態碼
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
錯誤處理:subprocess.check_call()
我們說過call執行返回一個狀態碼,我們可以通過check_call()函數來檢測命令的執行結果,如果不成功將返回 subprocess.CalledProcessError 異常
示例:
import subprocess try: subprocess.check_call("sdf",shell=True) except subprocess.CalledProcessError as err: print("Command Error",err)
捕獲輸出結果:subprocess.check_output()
call()方法啟動的進程,其標準輸入輸出會綁定到父進程的輸入和輸出。調用程序無法獲取命令的輸出結果。但可以通過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) #執行結果 Command Error Command "lT -l" returned non-zero exit status 127
直接處理管道:subprocess.Popen()
函數call(), check_call() 和 check_output() 都是Popen類的包裝器。直接使用Popen會對如何運行命令以及如何處理其輸入輸出有更多控制。如通過為stdin, stdout和stderr傳遞不同的參數。
與進程的單向通信:通過Popen()方法調用命令后執行的結果,可以設置stdout值為PIPE,再調用communicate()獲取結果,返回結果為tuple. 在python3中結果為byte類型,要得到str類型需要decode轉換一下
輸出結果(讀)
# 直接執行命令輸出到屏幕 >>> 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返回標準輸出或標準出錯信息 >>> 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) # 結果輸出到文件 >>> 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
與進程的雙向通信
proc = subprocess.Popen("cat", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) msg = "hello world".encode("utf-8") # 寫入到輸入管道 proc.stdin.write(msg) 11 # 輸入結果 stdout_value = proc.communicate() stdout_value (b"hello world", None) # 輸出結果 # 在需要進行相互交互的輸入輸出過程也可以使用shtin來實現 # 以下實現打開python3的終端,執行一個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()方法用于和子進程交互:發送數據到stdin,并從stdout和stderr讀數據,直到收到EOF。等待子進程結束。
捕獲錯誤輸出
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 查看子進程ID
Popen.returncode 獲取子進程狀態碼,0表示子進程結束,None未結束
在使用Popen調用系統命令式,建議使用communicate與stdin進行交互并獲取輸出(stdout),這樣能保證子進程正常退出而避免出現僵尸進程:
示例:
proc = subprocess.Popen("ls -l", shell=True, stdout=subprocess.PIPE) # 當前子進程ID proc.pid 5919 # 返回狀態None,進程未結束 print(proc.returncode) None # 通過communicate提交后 out_value = proc.communicate() proc.pid 5919 # 返回狀態為0,子進程自動結束 print(proc.returncode) 0
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44602.html
摘要:問題如何執行外部命令,如解決方案使用庫在之前,使用函數在及之后,使用函數討論命令的執行默認不需要環境,所以當你使用作為參數時,需要將置位,否則會報錯誤通常來說對于執行系統命令,我們會想到,但在官方文檔中已經建議了使 問題 如何執行外部命令,如ls -l 解決方案 使用subprocess庫 在Python 3.5之前,使用subprocess.call()函數 >>> import s...
摘要:以前我一直用處理一些系統管理任務因為我認為那是運行命令最簡單的方式我們能從官方文檔里讀到應該用模塊來運行系統命令模塊允許我們創建子進程連接他們的輸入輸出錯誤管道,還有獲得返回值。模塊打算來替代幾個過時的模塊和函數,比如命令。 以前我一直用os.system()處理一些系統管理任務,因為我認為那是運行linux命令最簡單的方式.我們能從Python官方文檔里讀到應該用subprocess...
摘要:原因很簡單,因為中的代表的就是當前執行的模塊名。缺點就是主程序會受待執行程序的影響,會出現待執行程序中拋異常或主動退出會導致主程序也退出的尷尬問題。總結來說就是,一個是在子進程中執行代碼,一個是在當前進程中執行代碼。 showImg(https://segmentfault.com/img/remote/1460000018607395?w=502&h=318); 相信剛接觸Pytho...
摘要:單元素元祖這是整數這才是元祖也許這兩行,你們當時疑惑過,并且現在也都知道了,當然重點并不在這里。。雖然我水平很垃圾,但是我知道匿名函數有一種執行方式叫做自執行。看吧,這就是版的匿名函數自執行方法。 單元素元祖: a = (1) # 這是整數1 a = (1,) # 這才是元祖 也許這兩行,你們當時疑惑過,并且現在也都知道了,當然重點并不在這里。。 我無聊的時候想過,為什么單...
摘要:可以執行命令的相關模塊和函數有廢棄廢棄廢棄,中被移除以上執行命令的相關的模塊和函數的功能均在模塊中實現,并提供了更豐富的功能。所以不能將設置為同時重定向子進程的標準輸入輸出與錯誤。同上用于設置子進程的當前目錄用于指定子進程的環境變量。 可以執行shell命令的相關模塊和函數有: os.system os.spawn os.popen --廢棄 popen --廢棄...
閱讀 2025·2023-04-25 14:50
閱讀 2907·2021-11-17 09:33
閱讀 2611·2019-08-30 13:07
閱讀 2838·2019-08-29 16:57
閱讀 908·2019-08-29 15:26
閱讀 3540·2019-08-29 13:08
閱讀 1990·2019-08-29 12:32
閱讀 3383·2019-08-26 13:57