python subprocess

鼠與我發表於2020-12-02

Intro

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.

即subprocess支援我們從當前程式生成子程式來執行command,雖然都是生成子程式,但是和fork不同,subprocess更specified於執行一個執行shell命令的子程式。

Use

subprocess.run(args,*,stdin=None,stdout=None,stderr=None,shell=False,
text=None,cwd=None,input=None,timeout=None)
該函式會spawn一個用於執行args的子程式,並返回一個CompletedProcess物件.

  • args可以是一個列表,也可以是一個string,如: ["ls","-l"]或"pwd".注意當args為string時,它只能單純的指定一個可執行檔案,不能帶任何引數,除非指定shell引數為True.( If passing a single string, either shell must be True or else the string must simply name the program to be executed without specifying any arguments.)
  • stdin、stdout、stderr執行了子程式的標準輸入、輸出、錯誤流,一般只有stdout和stderr會被用到,如不指定stdout,則標準輸出會被直接列印在螢幕上,一般使用subprocess.PIPE這個管道來指定stdout,而對於stderr則是subprocess.STDOUT,這樣標準輸出、錯誤會被暫存在管道中,並可由CompletedProcess物件取出.
  • shell引數則是配和args使用,如果args是string則最好把shell置為True.
  • text引數:If text mode is not used, stdin, stdout and stderr will be opened as binary streams. No encoding or line ending conversion is performed.
  • cwd引數指定一個path,使得子程式在args所代表的shell命令執行前先cd到指定的path下
  • input傳遞給Popen.communicate
  • timeout傳遞給Popen.communicate

對於subprocess.run返回的CompletedProcess物件,它有一些attributes可以方便我們獲得子程式執行命令的情況.

  • returncode 獲得子程式的返回值,0為成功執行.
  • args 子程式對應的args
  • stdout 假如在subprocess.run函式呼叫時指定PIPE的話,這裡會從管道中得到stdout結果,否則為None.
  • stderr 和stdout同理

不過,作為module級的函式,它實質上其實是透過class level的一些類和方法實現的,即是subprocess.Popen和Popen.communicate等.

subprocess.Popen(args,stdin=None,stdout=None,stderr=None,shell=False,
cwd=None,text=None)

使用該類時會建立一個子程式執行args並返回一個Popen例項物件.下面介紹該類的一些method:

  • poll 該方法check子程式是否結束,假如結束返回returncode,否則返回None.
  • terminate 該方法終結子程式
  • kill 該方法殺死子程式,與terminate的區別在於傳遞的SIGNAL的不同,terminate的結束更加politely,在windows上的兩者則無區別.
  • wait(timeout=None) 父程式等待子程式結束,超過timeout則報錯,raise a TimeExpired exception.
  • communicate(input=None,timeout=None) 該方法是與子程式進行溝通,即向input傳遞資料,timeout和上面相同,returns a tuple (stdout_data, stderr_data). The data will be strings if streams were opened in text mode; otherwise, bytes.

Popen的一些attributes:

  • stdin、stdout、stderr和之前的CompletedProcess同理
  • returncode 例項對應的子程式的返回值
  • args 例項對應的子程式的命令
  • pid 例項對應的子程式的pid

Cautions

Popen.wait will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that. 即Popen使用PIPE的時候最好不要使用wait方法,否則可能會引起deadlock,使用communicate會避免這一點。

對於subprocess.run函式所建立的子程式,父程式會自動等待子程式結束,而如果單獨使用subprocess.Popen,則父程式不會等待,可以使用Popen.wait,不過上文已經不建議使用該函式,不過其實Popen.communicate除了Interact with process的作用,還有Wait for process to terminate,所以上文才提到使用commnunicate替代wait+Popen.stdout,Popen.stderr.

相關文章