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)

其他

  1. args:啟動進程的參數,默認為字符串序列(列表或元組),也可為字符串(設為字符串時一般需將shell參數賦值為True);
  2. shell:shell為True,表示args命令通過shell執行,則可訪問shell的特性;
  3. check:check為True時,表示執行命令的進程以非0狀態碼退出時會拋出;subprocess.CalledProcessError異常;check為False時,狀態碼為非0退出時不會拋出異常;
  4. stdout、stdin、stderr:分別表示程序標準標輸出、輸入、錯誤信息;
  5. run函數返回值為CompletedProcess類,若需獲取執行結果,可通過獲取返回值的stdout和stderr來捕獲;
  6. check_output函數若需捕獲錯誤信息,可通過stderr=subprocess.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對象;

  1. args:需要執行的系統命令,可為字符串序列(列表或元組,shell為默認值False即可,建議為序列),也可為字符串(使用字符串時,需將shell賦值為True);
  2. shell:默認False,若args為序列時,shell=False;若args為字符串時,shell=True,表示通過shell執行命令;
  3. stdout、stdin、stderr:分別表示子程序標準輸出、標準輸入、標準錯誤,可為subprocess.PIPE、一個有效的文件描述符、文件對象或None。
    若為subprocess.PIPE:代表打開通向標準流的管道,創建一個新的管道;
    若為None:表示沒有任何重定向,子進程會繼承父進程;
    stderr也可為subprocess.STDOUT:表示將子程序的標準錯誤輸出重定向到了標準輸出
  4. bufsize:默認0;指定緩沖策略,0表示不緩沖,1表示行緩沖,其它整數表示緩沖區大小,負數表示使用系統
  5. cwd:默認None;若非None,則表示將會在執行這個子進程之前改變當前工作目錄;
  6. env:用于指定子進程的環境變量。若env為None,那么子進程的環境變量將從父進程中繼承;若env非None,則表示子程序的環境變量由env值來設置,它的值必須是一個映射對象。
  7. universal_newlines: 不同系統的換行符不同。若True,則該文件對象的stdin,stdout和stderr將會以文本流方式打開;否則以二進制流方式打開
  8. preexec_fn:只在Unix平臺下有效,用于指定一個可執行對象(callable object),它將在子進程運行之前被調用。
  9. Close_sfs:在windows平臺下,如果close_fds被設置為True,則新創建的子進程將不會繼承父進程的輸入、輸出、錯誤管道。我們不能將close_fds設置為True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
  10. startupinfo與createionflags只在windows下有效,它們將被傳遞給底層的CreateProcess()函數,用于設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。

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()

def subprocess_Popen1():print("***通過communicate函數分別輸出PopenObject對象的輸出流和錯誤流***")args = [["adb", "devices"], ["adb", "devices11"]]for arg in args:popen_object = subprocess.Popen(arg, stdout=subprocess.PIPE, stderr=subprocess.PIPE)object_stdout, object_stderr = popen_object.communicate()output = {"popen_object": popen_object,"object_stdout": object_stdout,"object_stderr": object_stderr}print(output)"""{'popen_object': <subprocess.Popen object at 0x0000000002212400>, 'object_stdout': b'List of devices attached \r\n106D111805005938\tdevice\r\n\r\n', 'object_stderr': b''}{'popen_object': <subprocess.Popen object at 0x0000000002577C18>, 'object_stdout': b'', 'object_stderr': b'Android Debug Bridge version 1.0.31\r\n\r\n -a .....}"""print("***通過stdout和stderr方法輸出PopenObject對象輸出流和錯誤流***")p0 = subprocess.Popen(["adb", "devices"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)object_stdout = p0.stdout.read()p0.stdout.close()object_stderr = p0.stderr.read()p0.stderr.close()print(object_stdout)        # 結果:b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'print(object_stderr)        # 結果:b''print("***Popen對象stdin寫入功能:使用stdout和stderr輸出")args = ["python", "python1"]for arg in args:p4 = subprocess.Popen([arg], shell=True, stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)p4.stdin.write("print('hello')")p4.stdin.close()out = p4.stdout.read()p4.stdout.close()err = p4.stderr.read()p4.stderr.close()print("out:%s err:%s" % (out, err))"""***Popen對象stdin寫入功能out:helloerr:out: err:'python1' 不是內部或外部命令,也不是可運行的程序或批處理文件。"""print("***Popen對象stdin寫入功能:使用communicate輸出")p4 = subprocess.Popen(["python"], stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)p4.stdin.write("print('hello')")output = p4.communicate()print(output)       # 結果:('hello\n', '')print("***不含encoding參數***")p1 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE)out1 = p1.stdout.readlines()print(out1)         # 結果: [b'List of devices attached \r\n', b'106D111805005938\tdevice\r\n', b'\r\n']print("***含encoding參數***")p2 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE, encoding="utf-8")out2 = p2.stdout.readlines()print(out2)         # 結果: ['List of devices attached \n', '106D111805005938\tdevice\n', '\n']print("***Popen對象檢查命令是否結束,等待進程結束")print(p2.poll())    # 結果: Noneprint(p2.wait())    # 結果: 0print(p2.poll())    # 結果: 0print("***Popen對象communicate函數,它會阻塞父進程直至子進程完成")p3 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE)out = p3.communicate()[0]print(out)          # 結果:b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'print(p3.poll())    # 結果:0
subprocess_Popen1()def subprocess_Popen2():"""1. 通過管道功能,實現adb shell ps | findstr top功能2. 直接為args賦值為一個字符串,實現adb shell ps | findstr top功能:return:"""print("***通過管道方式***")p1 = subprocess.Popen(["adb", "shell", "ps"], stdout=subprocess.PIPE)p2 = subprocess.Popen(["findstr", "top"], stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = p2.communicate()print(out, err)         # 結果:b'shell     8508  8504  2600   1044  c004e5f8 b6f40938 S top\r\r\n' b''print("***通過傳一個字符串方式***")p3 = subprocess.Popen("adb shell ps | findstr top", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = p3.communicate()print(out, err)         # 結果:b'shell     8508  8504  2600   1044  c004e5f8 b6f40938 S top\r\r\n' b''
subprocess_Popen2()

報錯解決

報錯信息

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')

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453886.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows下的FFmpeg 、MEncoder、MPlayer下載地址

視頻轉碼常用的是MEncoder&#xff0c;這個工具包含在MPlayer中&#xff0c;也可以使用FFmpeg&#xff0c;但據說有些格式轉換的時候效率不及MEcoder&#xff0c;所以能用MEncoder轉換的盡量用MEncoder轉換&#xff0c;由于MEncoder暫時還沒有研究&#xff0c;等研究過了再補充…

功率曲線k值_什么叫離心泵的流量——功率曲線?它們之間有什么關系?

流量和功率之間為正比例關系。流量增加時功率也增加&#xff0c;增加快、慢與比轉數有關。比轉數越小&#xff0c;流量增加后功率增加越快&#xff1b;比轉數越大&#xff0c;流量增加后功率增加越慢。 離心泵的性能參數與特性曲線泵的性能及相互之間的關系是選泵和進行流量調節…

什么是CI/CD

一、簡介 CI / CD的采用改變了開發人員和測試人員如何發布軟件。 最初是瀑布模型&#xff0c;后來是敏捷開發&#xff0c;現在是DevOps&#xff0c;這是現代開發人員構建出色的產品的技術路線。隨著DevOps的興起&#xff0c;出現了持續集成&#xff08;Continuous Integration…

FFmpeg在Windows系統下的編譯過程

由于FFMpeg是基于Linux開發的開源項目&#xff0c;源代碼和Windows下最常見的Visual Studio提供的C/C編譯器不兼容&#xff0c;因此它不能使用MSVC編譯。要想使用FFMpeg&#xff0c;最先要解決的問題就是在Windows下配置一個類似Linux的編譯環境&#xff0c;將FFMpeg編譯為二進…

centos 文件夾網絡連接_centos8 安裝后網絡不通及網絡配置

一 修改配置文件設置網絡時首先打開配置文件&#xff0c;配置文件默認如下所示&#xff0c;如果使用dhcp自動獲取ip&#xff0c;只需將ONBOOTno修改為ONBOOTno即可。#網卡配置文件按默認配置TYPEEthernetPROXY_METHODnoneBROWSER_ONLYnoBOOTPROTOdhcpDEFROUTEyesIPV4_FAILURE_F…

STM32 HAL庫詳解 及 手動移植

源&#xff1a; STM32 HAL庫詳解 及 手動移植轉載于:https://www.cnblogs.com/LittleTiger/p/8044047.html

Python 內置函數之 open (文件操作)

正常的文件操作都分三步走&#xff1a;打開文件&#xff0c;操作文件&#xff0c;關閉文件。 python open() 函數用于打開一個文件&#xff0c;創建一個 file 對象&#xff0c;相關的方法才可以調用它進行讀寫 語法 文件句柄 open(文件名,模式) 例如&#xff1a;f open(a…

windows系統下_ffmpeg編譯_2011年

ffmpeg開源庫在linux系統下弄的&#xff0c;是一個很全的音頻和視頻的編解碼庫要在windows下編譯出用于開發的lib庫確實比linux下要麻煩&#xff0c;百度了很久&#xff0c;參照別人的見解終于成功編譯出自己需要的可以用于開發的庫&#xff08;dll的形式&#xff0c;附帶dll的…

部署WEB項目到服務器(三)安裝mysql到linux服務器(Ubuntu)詳解

突發奇想&#xff0c;想在自己電腦上部署一個web網站。 1&#xff0c;首先是下載一個適合自己已安裝服務器版本的mysql數據庫。 這里使用網上的鏈接http://dev.mysql.com/downloads/mysql/5.6.html#downloads 或者使用代理網站上下載&#xff1a;https://mirrors.huaweicloud.c…

在Windows下編譯ffmpeg完全手冊

本文的內容幾乎全部來自于FFmpeg on Windows&#xff0c;但是由于國內的網絡封鎖&#xff0c;很難訪問這個域名下的內容&#xff0c;因此我一方面按照我自己的理解和實踐做了翻譯&#xff0c;另一方面也是為了能提供一個方便的參考方法。 注&#xff1a; 1. 對于compil…

padding和卷積的區別_TensorFlow筆記1——20.CNN卷積神經網絡padding兩種模式SAME和VALID...

第1種解說&#xff1a;(核心最后一張圖&#xff0c;兩種填充方式輸出的形狀尺寸計算公式)在用tensorflow寫CNN的時候&#xff0c;調用卷積核api的時候&#xff0c;會有填padding方式的參數&#xff0c;找到源碼中的函數定義如下&#xff08;max pooling也是一樣&#xff09;&am…

MORMOT數據庫連接池

MORMOT數據庫連接池 MORMOT封裝了一堆的PROPS控件&#xff0c;用于連接各種數據庫。 MORMOT的封裝是武裝到了牙齒的&#xff0c;這堆PROPS控件居然數據庫連接池也封裝好了。這就為我們省了不少事&#xff0c;筆者非常喜歡&#xff01; 下面拿TOleDBMSSQLConnectionProperties控…

循環神經網絡變形之 (Long Short Term Memory,LSTM)

1、長短期記憶網絡LSTM簡介 在RNN 計算中&#xff0c;講到對于傳統RNN水平方向進行長時刻序列依賴時可能會出現梯度消失或者梯度爆炸的問題。LSTM 特別適合解決這種需要長時間依賴的問題。 LSTM&#xff08;Long Short Term Memory&#xff0c;長短期記憶網絡&#xff09;是R…

Windows 系統下使用 MinGW + MSYS + GCC 編譯 FFMPEG

一定要按照順序操作&#xff0c;否則你很可能持續遇到很多奇怪的問題&#xff08;ffmpeg對編譯系統版本要求比較高&#xff09;。 1. www.mingw.org: 下載并安裝 MinGW 5.1.4 (http://jaist.dl.sourceforge.net/sourceforge/mingw/MinGW-5.1.4.exe)&#xff0c;安裝時選中 g, m…

eclipse怎樣改編碼格式_Eclipse中各種編碼格式及設置

操作系統&#xff1a;Windows 10(家庭中文版)Eclipse版本&#xff1a;Version: Oxygen.1a Release (4.7.1a)剛看到一篇文章&#xff0c;里面介紹說Ascii、Unicode是編碼&#xff0c;而GBK、UTD-8等是編碼格式。Java中的編碼問題(by 迷失之路)&#xff1a;https://www.cnblogs.c…

UE4 ShooterGame Demo的開火的代碼

之前一直沒搞懂按下鼠標左鍵開火之后&#xff0c;代碼的邏輯是怎么走的&#xff0c;今天看懂了之前沒看懂的部分&#xff0c;進了一步 ShooterCharacter.cpp void AShooterCharacter::OnStartFire() {AShooterPlayerController* MyPC Cast<AShooterPlayerController>(Co…

kafka 異常:return ‘<SimpleProducer batch=%s>‘ % self.async ^ SyntaxError: invalid syntax

Python3.X 執行Python編寫的生產者和消費者報錯&#xff0c;報錯信息如下&#xff1a; Traceback (most recent call last): File "mykit_kafka_producer.py", line 9, in <module> from kafka import KafkaProducer File "/usr/local/lib/python3.7/sit…

python 分布式計算框架_漫談分布式計算框架

如果問 mapreduce 和 spark 什么關系&#xff0c;或者說有什么共同屬性&#xff0c;你可能會回答他們都是大數據處理引擎。如果問 spark 與 tensorflow 呢&#xff0c;就可能有點迷糊&#xff0c;這倆關注的領域不太一樣啊。但是再問 spark 與 MPI 呢&#xff1f;這個就更遠了。…

Codeforces 899D Shovel Sale

題目大意 給定正整數 $n$&#xff08;$2\le n\le 10^9$&#xff09;。 考慮無序整數對 $(x, y)$&#xff08;$1\le x,y\le n, x\ne y$&#xff09;。 求滿足 「$xy$ 結尾連續的 9 最多」的數對 $(x,y)$ 的個數。 例子&#xff1a; $n50$&#xff0c;$(49,50)$ 是一個滿足條件的…

Windows系統使用minGW+msys 編譯ffmpeg 0.5的全過程詳述

一.環境配置 1.下載并安裝 MinGW-5.1.4.exe (http://jaist.dl.sourceforge.net/sourcef … -5.1.4.exe)&#xff0c;安裝時選中 g, mingw make。建議安裝到c:/mingw. 2.下載并安裝 MSYS-1.0.11-rc-1.exe (http://jaist.dl.sourceforge.net/sourcef … 1-rc-1.exe)&#xff0c;安…