python 内置模块 subprocess
1、介紹
subprocess模塊可以生成新的進程,連接到它們的input/output/error管道,同時獲取它們的返回碼。
2、基本操作方法
2.1、subprocess的run、call、check_call、check_output函數
subprocess.run(args[, stdout, stderr, shell ...])
- 執行args命令,返回值為CompletedProcess類;
- 若未指定stdout,則命令執行后的結果輸出到屏幕上,函數返回值CompletedProcess中包含有args和returncode;
- 若指定有stdout,則命令執行后的結果輸出到stdout中,函數返回值CompletedProcess中包含有args、returncode和stdout;
- 若執行成功,則returncode為0;若執行失敗,則returncode為1;
- 若想獲取args命令執行后的輸出結果,命令為:output = subprocess.run(args, stdout=subprocess.PIPE).stdout
subprocess.call(args[, stdout, ...])
- 執行args命令,返回值為命令執行狀態碼;
- 若未指定stdout,則命令執行后的結果輸出到屏幕;
- 若指定stdout,則命令執行后的結果輸出到stdout;
- 若執行成功,則函數返回值為0;若執行失敗,則函數返回值為1;
- (類似os.system)
subprocess.check_call(args[, stdout, ...])
- 執行args命令,返回值為命令執行狀態碼;
- 若未指定stdout,則命令執行后的結果輸出到屏幕;
- 若指定stdout,則命令執行后的結果輸出到stdout;
- 若執行成功,則函數返回值為0;若執行失敗,拋出異常;
- (類似subprocess.run(args, check=True))
subprocess.check_output(args[, stderr, ...])
- 執行args命令,返回值為命令執行的輸出結果;
- 若執行成功,則函數返回值為命令輸出結果;若執行失敗,則拋出異常;
- (類似subprocess.run(args, check=True, stdout=subprocess.PIPE).stdout)
其他
示例
# ################### subprocess.run 使用 def subprocess_run():result1 = subprocess.run(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.run("adb devices", shell=True, check=True)print("result2:", result2)print("----------")result3 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE)print("result3:", result3)print(type(result3)) subprocess_run()""" 輸出如下 List of devices attached 338b123f0504 deviceresult1: CompletedProcess(args=['adb', 'devices'], returncode=0) ---------- List of devices attached 338b123f0504 deviceresult2: CompletedProcess(args='adb devices', returncode=0) ---------- result3: CompletedProcess(args=['adb', 'devices'], returncode=0, stdout=b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n') <class 'subprocess.CompletedProcess'> """# ################### subprocess.call使用 def subprocess_call():result1 = subprocess.call(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.call(["adb", "devices"], stdout=subprocess.PIPE)print("result2:", result2) subprocess_call()"""結果 List of devices attached 338b123f0504 deviceresult1: 0 ---------- result2: 0 """# ################### subprocess.check_call def subprocess_check_call():result1 = subprocess.check_call(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.check_call(["adb", "devices"], stdout=subprocess.PIPE)print("result2:", result2) subprocess_check_call()"""結果 List of devices attached 338b123f0504 deviceresult1: 0 ---------- result2: 0 """# ################### subprocess.check_output def subprocess_check_output():result1 = subprocess.check_output(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE).stdoutprint("result2:", result2) subprocess_check_output()"""結果 result1: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n' ---------- result2: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n' """2.2、subprocess的getoutput、getstatusoutput函數
subprocess.getoutput(cmd)
執行cmd命令,返回值為命令執行的輸出結果(字符串類型);執行失敗,不會拋出異常(類似os.popen(cmd).read());
cmd:參數,字符串類型;
subprocess.getstatusoutput(cmd)
執行cmd命令,返回值為元組類型(命令執行狀態, 命令執行的輸出結果);元組中命令執行狀態為0,表示執行成功;命令執行狀態為1,表示執行失敗;
cmd:參數,字符串類型;
示例
# subprocess.getoutput或getstatusoutput使用 def subprocess_get_output():result1 = subprocess.getoutput("adb devices")print("result1:", result1)print(type(result1))print("**** subprocess.getstatusoutput ****")result2 = subprocess.getstatusoutput("adb devices")print("result2:", result2)print(type(result2)) subprocess_get_output() """結果 **** subprocess.getoutput **** result1: List of devices attached 338b123f0504 device<class 'str'> **** subprocess.getstatusoutput **** result2: (0, 'List of devices attached \n338b123f0504\tdevice\n') <class 'tuple'> """3、 subprocess.Popen類
subprocess.Popen類用于在一個新進程中執行一個子程序,上述subprocess函數均是基于subprocess.Popen類;
subprocess.Popen(args[, bufsize, stdin, stdout, stderr, ...]) 語法
Popen類的構造函數,返回結果為subprocess.Popen對象;
若為subprocess.PIPE:代表打開通向標準流的管道,創建一個新的管道;
若為None:表示沒有任何重定向,子進程會繼承父進程;
stderr也可為subprocess.STDOUT:表示將子程序的標準錯誤輸出重定向到了標準輸出
subprocess.Popen對象常用方法
下列 PopenObject 為 subprocess.Popen 對象
- PopenObject.poll() :用于檢查命令是否已經執行結束,若結束返回狀態碼;若未結束返回None;
- PopenObject.wait([timeout, endtime]):等待子進程結束,并返回狀態碼;若超過timeout(s)進程仍未結束,則拋出異常;
- PopenObject.send_signal(signal):發送信號signal給子進程;
- PopenObject.terminate():停止子進程;在windows平臺下,該方法將調用Windows API TerminateProcess()來結束子進程。
- PopenObject.kill():殺死子進程;
- PopenObject.communicate([input, timeout]):與進程進行交互(如向stdin發送數據,或從stdout和stderr中讀取數據),它會阻塞父進程,直到子進程完成;注意:如果希望通過進程的stdin向其發送數據,在創建Popen對象的時候,參數stdin必須被設置為PIPE。同樣,如果希望從stdout和stderr獲取數據,必須將stdout和stderr設置為PIPE。
- input:表示將發送到子進程的字符串數據,默認為None;
- timeout:超時判斷,若超過timeout秒后仍未結束則拋出TimeoutExpired異常;
- communicate返回值:一個元組(stdout_data, stderr_data)
- 要注意的是,subprocess.PIPE實際上為文本流提供一個緩存區。直到communicate()方法從PIPE中讀取出PIPE中的文本.此方法比wait()好用。https://www.jianshu.com/p/8e582146bd4c
- PopenObject.pid:獲取子進程的進程ID。
- PopenObject.returncode:獲取進程的返回值。如果進程還沒有結束,返回None。
subprocess.Popen 對象的文本或字節流控制
-
PopenObject.stdin:
若PopenObject中stdin為PIPE,則返回一個可寫流對象;若encoding或errors參數被指定或universal_newlines參數為True,則此流是一個文件流,否則為字節流。
若PopenObject中stdin不是PIPE,則屬性為None。
stdin輸入流非None,可執行寫操作即PopenObject.stdin.write(s) -
PopenObject.stdout:
若PopenObject中stdout為PIPE,則返回一個可讀流對象;若encoding或errors參數被指定或universal_newlines參數為True,則此流是一個文件流,否則為字節流。
若PopenObject中stdout不是PIPE,則屬性為None。
stdout輸出流非None,可執行讀操作即PopenObject.stdout.read()或.readlines() -
PopenObject.stderr:
若PopenObject中stderr為PIPE,則返回一個可讀流對象;若encoding或errors參數被指定或universal_newlines參數為True,則此流是一個文件流,否則為字節流。
若PopenObject中stderr不是PIPE,則屬性為None。
stderr錯誤流非None,可執行讀操作即PopenObject.stderr.read()或.readlines()
報錯解決
報錯信息
Traceback (most recent call last):File "C:\Users\fenglepeng\.conda\envs\py37\lib\threading.py", line 926, in _bootstrap_innerself.run()File "C:\Users\fenglepeng\.conda\envs\py37\lib\threading.py", line 870, in runself._target(*self._args, **self._kwargs)File "C:\Users\fenglepeng\.conda\envs\py37\lib\subprocess.py", line 1267, in _readerthreadbuffer.append(fh.read()) UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 421: illegal multibyte sequence解決
# 參數中增加 encoding='utf-8' sub = subprocess.Popen(command, shell=True, cwd=cwd, universal_newlines=True,stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.PIPE, encoding='utf-8')?
總結
以上是生活随笔為你收集整理的python 内置模块 subprocess的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转C#网页抓取
- 下一篇: Python 内置模块之 时间模块 ti