1、subprocess 模塊簡介html
subprocess最先是在2.4版本中引入的。
subprocess模塊用來生成子進程,並能夠經過管道鏈接它們的輸入/輸出/錯誤,以及得到它們的返回值。
它用來代替多箇舊模塊和函數:
os.system
os.spawn*
os.popen*
popen2.*
commands.*python
1.1. 使用 subprocess模塊shell
啓動子進程的推薦方式是使用下面的便利功能。
當這些還不能知足需求時,就須要使用底層的Popen接口。windows
1. subprocess.call安全
語法: subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) 語義: 運行由args指定的命令,直到命令結束後,返回 返回碼的屬性值。 示例代碼: >>> subprocess.call(["ls", "-l"]) 0 >>> subprocess.call("exit 1", shell=True) 1 WARNING: 使用 shell=True 是一種安全保護機制。 NOTE: 在使用這個函數時,不要使用 stdout=PIPE 或 stderr=PIPE 參數, 否則會致使子進程輸出的死鎖。 若是要使用管道,能夠在 communicate()方法中使用Popen 示例代碼: import subprocess rc = subprocess.call(["ls","-l"])
經過一個shell來解釋一整個字符串:
ide
import subprocess out = subprocess.call("ls -l", shell=True) out = subprocess.call("cd ..", shell=True)
使用了shell=True這個參數。
這個時候,咱們使用一整個字符串,而不是一個表來運行子進程。
Python將先運行一個shell,再用這個shell來解釋這整個字符串。函數
shell命令中有一些是shell的內建命令,這些命令必須經過shell運行,$cd。
shell=True容許咱們運行這樣一些命令。ui
2. subprocess.check_callspa
語法: subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) 語義: 運行由args指定的命令,直到命令執行完成。 若是返回碼爲零,則返回。不然,拋出 CalledProcessError異常。 CalledProcessError對象包含有返回碼的屬性值。
上面顯示的參數僅僅是最多見的,下面是用戶更經常使用的參數。
示例代碼以下:.net
>>> >>> subprocess.check_call(["ls", "-l"]) 0 >>> subprocess.check_call("exit 1", shell=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
這個函數在python 2.5版本中引入。
WARNING: 使用 shell=True 是一種安全機制。
NOTE: 不要在這個函數中使用 stdout=PIPE 或 stderr=PIPE, 不然會形成子進程死鎖。
若是須要使用管道,能夠在 communicate()方法中使用Popen.
3. subprocess.check_output
語法: subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False) 語義: 運行args定義的命令,並返回一個字符串表示的輸出值。 若是返回碼爲非零,則拋出 CalledProcessError異常。 示例代碼: >>> >>> subprocess.check_output(["echo", "Hello World!"]) 'Hello World!\n' >>> subprocess.check_output("exit 1", shell=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 若是要捕捉結果中的標準錯誤,使用 stderr=subprocess.STDOUT參數: >>> >>> subprocess.check_output( ... "ls non_existent_file; exit 0", ... stderr=subprocess.STDOUT, ... shell=True) 'ls: non_existent_file: No such file or directory\n'
這個函數在python 2.7版本中引入。
WARNING: 使用 shell=True 是一種安全機制。
NOTE: 不要在這個函數中使用 stdout=PIPE 或 stderr=PIPE, 不然會形成子進程死鎖。
若是須要使用管道,能夠在 communicate()方法中使用Popen.
4.subprocess.Popen(...)
用於執行復雜的系統命令
參數:
·args:shell命令,能夠是字符串或者序列類型(如:list,元組)
·bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝
·stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄
·preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用
·close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
·shell:同上
·cwd:用於設置子進程的當前目錄
·env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
·universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n
·startupinfo與createionflags只在windows下有效
將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等
import subprocess ret1 = subprocess.Popen(["mkdir","t1"]) ret2 = subprocess.Popen("mkdir t2", shell=True)
終端輸入的命令分爲兩種:
·輸入便可獲得輸出,如:ifconfig
·輸入進行某環境,依賴再輸入,如:python
import subprocess obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close()print(cmd_out)print(cmd_error)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") out_error_list = obj.communicate()print(out_error_list)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list)
要注意的是,communicate()是Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成。
能夠利用communicate()方法來使用PIPE給子進程輸入:
import subprocess child = subprocess.Popen(["cat"], stdin=subprocess.PIPE) child.communicate("vamei")
啓動子進程以後,cat會等待輸入,直到咱們用communicate()輸入"vamei"。
詳文參見:http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html