<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 概述 subprocess模塊中只定義了一個類:Popen。可以使用Popen來創建進程,并與進程進行復雜的交互。它的構造函數如下。 --- ### Popen使用示例 示例1,使用shlex.split先對參數進行處理 ``` >>> import shlex, subprocess >>> command_line = input() /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> print(args) ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Success! ``` 示例2. 直接使用列表作為參數 ``` Popen(['/bin/sh', '-c', args[0], args[1], ...]) ``` 示例3. 這個上下文管理器在python3中才可以使用 ``` with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read()) ``` --- ### subprocess.Popen參數 ``` subprocess.Popen(args, bufsize=0, executable=None, shell=False, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False,cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0) ``` `參數args`:**字符串**或者**序列類型**(如:list,元組),用于指定進程的可執行文件及其參數。如果是序列類型,第一個元素通常是可執行文件的路徑。 `參數bufsize`:指定緩沖。 `參數executable`: 用于指定可執行程序。一般情況下我們通過args參數來設置所要運行的程序。如果將參數shell設為True,executable將指定程序使用的shell。 `參數stdin, stdout, stderr`: 分別表示程序的標準輸入、輸出、錯誤句柄。他們可以是PIPE,文件描述符或文件對象,也可以設置為None,表示`從父進程繼承`。 `參數preexec_fn`: 只在Unix平臺下有效,用于指定一個可執行對象(callable object),它將在子進程運行之前被調用。 `參數shell`: 設為true,程序將通過shell來執行。 `參數cwd`: 用于設置子進程的當前目錄。 `參數env`: 是字典類型,用于指定子進程的環境變量。如果env = None,子進程的環境變量將從父進程中繼承。 `參數Universal_newlines`: 不同操作系統下,文本的換行符是不一樣的。如:windows下用'\r\n'表示換,而Linux下用'\n'。如果將此參數設置為True,Python統一把這些換行符當作'\n'來處理。 --- ### subprocess.Popen的方法 * Popen.poll() 用于檢查子進程是否已經結束。設置并返回returncode屬性。 * Popen.wait() 等待子進程結束。設置并返回returncode屬性。 * Popen.communicate(input=None) 與子進程進行交互。向stdin發送數據,或從stdout和stderr中讀取數據。可選參數input指定發送到子進程的參數。Communicate()返回一個元組:`(stdoutdata, stderrdata)`。注意:如果希望通過進程的stdin向其發送數據,在創建Popen對象的時候,參數stdin必須被設置為PIPE。同樣,如果希望從stdout和stderr獲取數據,必須將stdout和stderr設置為PIPE。 * Popen.send_signal(signal) 向子進程發送信號。 * Popen.terminate() 停止(stop)子進程。在windows平臺下,該方法將調用Windows API TerminateProcess()來結束子進程。 * Popen.kill() 殺死子進程。 * Popen.stdin 如果在創建Popen對象是,參數stdin被設置為PIPE,Popen.stdin將返回一個文件對象用于策子進程發送指令。否則返回None。 * Popen.stdout 如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用于策子進程發送指令。否則返回None。 * Popen.stderr 如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用于策子進程發送指令。否則返回None。 * Popen.pid 獲取子進程的進程ID。 * Popen.returncode 獲取進程的返回值。如果進程還沒有結束,返回None。 下面是一個非常簡單的例子,來演示supprocess模塊如何與一個控件臺應用程序進行交互。 --- ### supprocess其他 * subprocess.PIPE 在創建Popen對象時,subprocess.PIPE可以作為初始化stdin,stdout或stderr參數。表示與子進程通信的標準流。 * subprocess.STDOUT 創建Popen對象時,用于初始化stderr參數,表示將錯誤通過標準輸出流輸出。 * subprocess.call(\*popenargs, \*\*kwargs) 運行命令。該函數將一直等待到子進程運行結束,并返回進程的`returncode`。如果子進程不需要進行交互,就可以使用該函數來創建。 > 報錯是shell錯誤,無法捕捉 * subprocess.check_call(\*popenargs, \*\*kwargs) 與subprocess.call(\*popenargs, \*\*kwargs)功能一樣,只是如果子進程返回的returncode不為0的話,將觸發CalledProcessError異常。在異常對象中,包括進程的`returncode`信息。 > 報錯是python錯誤,在python中可以捕捉 ### 設置超時時間 通過改寫,設置腳本執行的超時時間 ~~~ #!/usr/bin/env python # coding=utf-8 import shlex import datetime import subprocess import time def execute_command(cmdstring, cwd=None, timeout=None, shell=False): """執行一個SHELL命令封裝了subprocess的Popen方法, 支持超時判斷,支持讀取stdout和stderr 參數: cwd: 運行命令時更改路徑,如果被設定,子進程會直接先更改當前路徑到cwd timeout: 超時時間,秒,支持小數,精度0.1秒 shell: 是否通過shell運行 Returns: return_code Raises: Exception: 執行超時 """ if shell: cmdstring_list = cmdstring else: cmdstring_list = shlex.split(cmdstring) if timeout: end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) #沒有指定標準輸出和錯誤輸出的管道,因此會打印到屏幕上; sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,shell=shell,bufsize=4096) #subprocess.poll()方法:檢查子進程是否結束了,如果結束了,設定并返回碼,放在subprocess.returncode變量中 while sub.poll() is None: time.sleep(0.1) if timeout: if end_time <= datetime.datetime.now(): raise Exception("Timeout:%s"%cmdstring) return str(sub.returncode) if __name__=="__main__": print execute_command("sleep 5", timeout=2) ~~~ --- ### Popen的wait方法和communicate方法比較 Popen的wait方法之后程序一直沒有返回,原因是wait是有可能產生死鎖。 使用 subprocess 模塊的 Popen 調用外部程序,如果 stdout 或 stderr 參數是 PIPE,并且程序輸出超過操作系統的 pipe size時,如果使用 Popen.wait() 方式等待程序結束獲取返回值,會導致死鎖,程序卡在 wait() 調用上。 `ulimit -a` 看到的 pipe size 是 4KB,那只是每頁的大小,查詢得知 Linux 默認的 pipe size 是 `64KB`。 #### 對wait方法和communicate方法進行測試 ``` #!/usr/bin/env python # coding: utf-8 import subprocess def test(size): print 'start' cmd = 'dd if=/dev/urandom bs=1 count=%d 2>/dev/null' % size p = subprocess.Popen(args=cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) p.communicate() #p.wait() print 'end' ``` 測試結果 p.wait工作時,64kb時工作正常,64k+1時,程序卡住,產生死鎖。 p.communicate工作時,兩種情況下都可以正常工作。 ``` # 64KB test(64 * 1024) # 64KB + 1B test(64 * 1024 + 1) ``` 官方文檔里推薦使用 `Popen.communicate()`。這個方法會把輸出放在`內存`,而不是管道里,所以這時候上限就和內存大小有關了。而且如果要獲得程序返回值,可以在調用 Popen.communicate() 之后取 Popen.returncode 的值。 結論 如果使用 subprocess.Popen,應該使用 Popen.communicate() 來等待外部程序執行結束。 --- ### subprocess的兩種方法 阻塞和非阻塞 1)如果想調用之后直接阻塞到子程序調用結束 ``` #start and block until done import shlex, subprocess cmd = 'dd if=/dev/zero of=bigfile bs=1M count=32' cmd = shlex.split(cmd) subprocess.call(cmd) ``` 2)非阻塞的時候方式 ``` #start and process things, then wait from subprocess import Popen,PIPE cmd = 'dd if=/dev/zero of=bigfile bs=1M count=32' p = Popen(args=cmd, shell=True, stdout=PIPE,stderr=PIPE) print p.communicate() print 'end...' ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看