subprocess(python3.7)
subprocess 主要是為了替換一下的模塊函數,允許你執行一些命令,並獲取返回的狀態碼和 輸入,輸出和錯誤信息。
os.system
os.spawn*
subprocess 有好多方法,本文主要在總結下之間的區別是什么,最后官方推薦使用哪個。
subprocess的主要方法:
subprocess.run(),subprocess.Popen(),subprocess.call #這些模塊都是基於Popen的
Python 3.5 之前
subprocess.call //call 系列 都是等待命令執行完, Wait for command to complete
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)
只返回執行結果的code 等同於subprocess.run(args).returncode
Note Do not use stdout=PIPE or stderr=PIPE with this function. The child process will block if it generates enough output to a pipe to fill up the OS pipe buffer as the pipes are not being read from.
############例子###
ret=subprocess.call(['ls', '-l']) # ret 程序執行結果返回值,正確執行都是0
----------------------------捕獲輸出結果到一個文件里Redirecting STDOUT to a File---
with open('joe.txt', 'w') as f: # 執行后joe.txt 文件內容為 Wed May 15 17:07:59 CST 2019
subprocess.call(['date'], stdout=f)
-------捕獲輸出結果到字符串,Redirecting STDOUT to strings---
ret=subprocess.check_output() #ret 為output內容(命令輸出的內容) 等同於run(..., check=True, stdout=PIPE).stdout
-------------------
subprocess.check_call() #和 subprocess.call 一樣,只是返回值不是0就引起異常,raise CalledProcessError ,等同於 subprocess.run(…, check=True)
-----輸入stdin ----------
with open('joe.txt', 'r') as fr
subprocess.call(['cat'], stdin=f)
-------
######################################################
subprocess.Popen() #最基本的subprocess模塊
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
p = subprocess.Popen(['ls', '-l']) #返回的p是Popen 對象
p(Popen對象) 有一下方法
p.poll() 檢查子進程(cmd) 是否結束 ,如果沒有結束會返回None,結束就返回return returncode
p.returncode 程序之后后的返回碼,一般正常結束會返回0,否則會返回其他值
p.wait() 等待子進程結束,然后返回returncode值
If the process does not terminate after timeout seconds, raise a TimeoutExpired exception. It is safe to catch this exception and retry the wait.
Note This 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.
Note The function is implemented using a busy loop (non-blocking call and short sleeps). Use the asyncio module for an asynchronous wait: see asyncio.create_subprocess_exec.
p.communicate() 和子進程交互,返回一個元祖,returns a tuple (stdout_data, stderr_data)
p.terminate() 終止子進程,相當於發送SIGTERM 信號,相當於kill (后面不加參數)
p.kill() 終止子進程,相當於發送SIGKILL 信號,相當於kill -9
p.stdin,p.stdout,p.stderr 分別是輸入,輸出,錯誤輸出,在python3中都是byte類型需要decode轉化
p.returncode() 程序的返回狀態 ,程序沒有結束的話會返回None
p.pid 返回程序的 pid
p.send_signal(signal) 發送一個信號給子進程
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
Popen 參數:
------
args, a sequence of program arguments or else a single string(參數是一個序列如,列表,元祖等。或者參數是一個字符串),默認情況下,如果args是序列,則要執行的程序是args中的第一項。如果args是一個字符串,需要設置shell=True,即開啟一個shell 執行一個字符串的命令,或者序列的第一項
-----
bufsize 參數,stdin,stdout,stderr的緩存參數
executable 參數
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ,shell=True時 executable=, 用於替換系統默認的shell(一般是bash),
p = subprocess.Popen('echo $0',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,executable='/bin/zsh') out,_=p.communicate() print(out.decode())
輸出>>>/bin/zsh
@@@@@@@@@@@@@@@@@@@@@@@@@ shell=False時 executable=xxx,xxx會替換序列的第一項,一下'ls' 替換了'cat' 最終執行了 ls 'a.py','a.txt','b.txt'
p = subprocess.Popen(['cat','a.py','a.txt','b.txt'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,executable='ls') out,_=p.communicate() print(out.decode())
輸出>>>a.py a.txt b.txt
python3.5 以后官方推薦使用run
p=subprocess.run(args, ***, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
run 也是需要等進程結束后才返回結果,所以沒有結束p.stdout等就不會輸出結果
run的參數,和Popen 一樣
capture_output =true 相當於stdout=PIPE and stderr=PIPE
timeout 設置子進程超時時間,超時引起 TimeoutExpired異常
The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated
input=xxx 相當於 Popen.communicate(xxx)和自動創建 stdin=PIPE
The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if encoding or errors is specified or text is true. When used, the internal Popen object is automatically created with stdin=PIPE, and the stdin argument may not be used as well.
check check=True 如果程序返回狀態碼不是0 就引起異常CalledProcessError
If check is true, and the process exits with a non-zero exit code, a CalledProcessErrorexception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
p=subprocess.run(), 執行run后會返回 CompletedProcess類型 實例 P
實例P 有如下方法
p.args
p.returncode
p.stdout
p.stderr
p.check_returncode

