可以執行shell命令的相關模塊和函數有:
- os.system
- os.spawn*
- os.popen* --廢棄
- popen2.* --廢棄
- commands.* --廢棄,3.x中被移除
上面這些命令,可以使用subprocess完美的實現,而且具有豐富的功能:
call: python3.5以下才有, python3.5及以上變成run方法
執行命令,返回狀態碼
>>> a = subprocess.call('whoami') huangxm-pc\huangxm >>> print(a) 0
執行一個帶參數的命令
>>> subprocess.call('ls -l') Traceback (most recent call last): File "<stdin>", line 1, in <module>
報錯了,對於這種可以加上shell=True, 表示完全當成shell命令執行
>>> subprocess.call('ls -l', shell=True) total 48 drwxr-xr-x 5 huanghao huanghao 4096 Mar 12 18:42 day7 drwxrwxrwx 2 huanghao huanghao 4096 Oct 19 22:42 Desktop
check_call
執行命令,如果執行狀態碼是 0 ,則返回0,否則拋異
>>> subprocess.check_call('cat /etc/passwd | grep root', shell=True) root:x:0:0:root:/root:/bin/bash 0 >>> subprocess.check_call('cat /etc/passwddd | grep root', shell=True) #執行失敗,拋出異常 cat: /etc/passwddd: No such file or directory Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.4/subprocess.py", line 557, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'cat /etc/passwddd | grep root' returned non-zero exit status 1
check_output
執行命令,如果執行狀態碼是 0 ,則返回0,否則拋異
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()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等
a = subprocess.Popen('ipconfig', shell=True) print(a) 執行結果 <subprocess.Popen object at 0x0000000002809240><subprocess.Popen object at 0x0000000002809240>
命令成功執行了,但是沒有獲得到結果,怎么獲得結果呢?
a = subprocess.Popen('ipconfig', shell=True, stdout=subprocess.PIPE).stdout.read() print(str(a, 'gbk')) #winodws中文是gbk
有時候我們並不是只這樣運行命令,而是需要進入一些目錄去執行一些命令,比如我們要在D盤建立一個文件夾:
a = subprocess.Popen('mkdir aaaaa', shell=True, cwd='C:/')
執行之后,到C盤看一下,有沒有一個aaaaa的文件夾。
再來看一個復雜點的:
第一步:先在D盤根目錄建立一個文件aa.py,內容如下:
def add(): x = input('input x:').strip() print('\n') y = input('input y:').strip() print('\n') print('the result is ', int(x)+int(y)) if __name__ == "__main__": add()
第二步:執行下面的代碼
obj = subprocess.Popen('python3 D:/aa.py', shell=True, cwd='c:/python34', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write(b'1\n') obj.stdin.write(b'2\n') obj.stdin.close() cmd_out = str(obj.stdout.read(), 'gbk') obj.stdout.close() print(cmd_out)
第三步:查看執行結果
input x: input y: the result is 3
在提示要輸入的時候,我們根本就沒有在鍵盤上輸入,因為stdin.write已經幫我們完成了輸入。 然后程序通過stdout.read()將結果讀取出來。如果程序執行中發生錯誤,還可以能過obj.stderr.read()獲取錯誤信息。