python3的subprocess的各個方法的區別(-)


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

 -----

stdin=None, stdout=None, stderr=None 和輸入,輸出,錯誤輸出有關,

想要捕捉這些信息可以設置為 將值設置為subprocess.PIPE,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE 如果想要達到2>&1 可以設置為stdout=subprocess.PIPE,stderr=subprocess.STDOUT 這些內容 stdin 如輸入("haha") 可以通過p.stdin.write(b"hahha");p.stdin.close() 或者 out,_=p.communicate(b'haha') stdout,stderr 可以通過p.stdout.readline(),p.stderr.readline() [就是文件描述符的一些參數如read(),readline等]

 

------

 

close_fds=True 子進程是否繼承文件描述符,如果false 將關閉除了0,1,2之外的所有文件描述符。 print( p.stdin.fileno()) #查看自身對應的(stdin/stdout)的文件描述符 參考一下遇到的問題close_fds(python2.x遇到的問題???!!!) https://stackoverflow.com/questions/19950185/python-close-fds-not-clear http://drmingdrmer.github.io/tech/programming/2017/11/20/python-concurrent-popen.html

-------

shell=True 是否在shell中執行,參考args 說明

--------

cwd 當前的工作目錄,如果有值,就會進入cd 到這個目錄執行args命令

-----

text=True,和universal_newlines=True一樣,universal_newlines只是為了向后兼容 都是讓stdxxx以文本模式輸出,而不是默認的二進制模式

If encoding or errors are specified, or text is true, the file objects stdin, stdout and stderr are opened in text mode with the specified encoding and errors, as described above in Frequently Used Arguments. The universal_newlines argument is equivalent to text and is provided for backwards compatibility. By default, file objects are opened in binary mode.

-----

 

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

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM