日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 内置模块 subprocess

發布時間:2023/12/20 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)

其他

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

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

    ?

    總結

    以上是生活随笔為你收集整理的python 内置模块 subprocess的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。