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.