容許你生成一個或多個進程,而且能夠跟它交互,而且獲取返回的結果,這個模塊想要替換掉幾個老的方法: os.system os.spawn* 因此之後跟系統交互的命令,儘可能用subprocess 建議調用subprocess的run()方法去跟系統進行調用,更高級的方法,使用popen() ;run()方法其實就是封裝的popen。 run()方法在python3.5纔有,python2.x沒有,2.x用subprocess.call(),固然python3.X版本也支持call()
subprocess.call subprocess.call("df -lh",shell=True) 或者 subprocess.call(["df","-lh"]) 若是想獲取到執行內容: a = subprocess.Popen("df -lh",shell=True,stdout=subprocess.PIPE) a.stdout.read() subprocess.check_call 執行命令,若是執行狀態碼是 0 ,則返回0,不然拋異常 subprocess.check_call(["ls","-l"]) subprocess.check_call("exit 1",shell=True) 拋出異常:subprocess.CalledProcessError: subprocess.check_output 執行命令,若是狀態碼是 0 ,則返回執行結果,不然拋異常 subprocess.check_output(["echo","hello world!"]) 返回:'hello world!\n' subprocess.check_output("exit 1",shell=True) 剖出異常:subprocess.CalledProcessError 執行命令,並返回結果,注意是返回結果,不是打印,下例結果返回給res res = subprocess.getoutput("ls /bin/sh") res 輸出:'/bin/sh' subprocess.getstatusoutput 接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果 subprocess.getstatusoutput("ls /bin/ls") 返回:(0, '/bin/ls') subprocess.getoutput 接收字符串格式命令,並返回結果 subprocess.getoutput("ls /bin/ls") 返回:'/bin/ls'
上邊的subprocess方法,底層都是封裝的subprocessPopenpython
poll() Check if child process has terminated. Returns returncode wait() Wait for child process to terminate. Returns returncode attribute. terminate() 殺掉所啓動進程 communicate() 等待任務結束 stdin 標準輸入 stdout 標準輸出 stderr 標準錯誤 pid The process ID of the child process. Popen例子: p = subprocess.Popen("df -lh|grep root",stdin=subproce p.stdout.read() 輸出:b'/dev/mapper/cl-root 38G 5.7G 32G 16% /\n'
subprocess.run(["ls","-lh"]) subprocess.run("exit 1",shell=True,check=True) 拋出異常:subprocess.CalledProcessError subprocess.run(["ls","-l","/dev/null"],stdout=subprocess.PIPE) 輸出: 以下:CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw-. 1 root root 1, 3 Jan 3 11:16 /dev/null\n') 調用和系統之間的操做,推薦subprocess.run() ,由於它早晚要替換掉sys.system ; run()方法能夠知足大部分的需求,若是要進行一些複雜的交互的話,還能夠用subprocessPopen() 如: p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE) print (p.stdout.read()) 輸出:b'0 -r--------. 1 root root 128T Jan 23 14:58 /proc/kcore\n1.9G -rw-------. 1 root root 100G Jan 8 17:48 /var/lib/docker/devicemapper/devicemapper/data\n3.8M -rw-------. 1 root root 2.0G Jan 8 17:48 /var/lib/docker/devicemapper/devicemapper/metadata\n'
用於執行復雜的系統命令 參數: 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()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等 終端輸入的命令分爲兩種: 輸入便可獲得輸出:如 ifocnfig 輸入進行某環境,依賴某環境再輸入:如 python 須要交互的命令示例: import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write('print 1 \n ') obj.stdin.write('print 2 \n ') obj.stdin.write('print 3 \n ') #當從這裏開始就報錯了。 obj.stdin.write('print 4 \n ') out_error_list = obj.communicate("timeout=10") print out_error_list 輸出: ('', ' File "<stdin>", line 2\n print 2 \n ^\nIndentationError: unexpected indent\n') subprocess實現iptables 清規則的時候 sudo 自動輸入密碼 import subprocess def mypass(): mypass = '123' # or get the password from anywhere return mypass echo = subprocess.Popen(['echo', mypass()], stdout=subprocess.PIPE, ) sudo = subprocess.Popen(['sudo', '-S', 'iptables', '-L'], stdin=echo.stdout, stdout=subprocess.PIPE, ) end_of_pipe = sudo.stdout print ("Password ok \n Iptables Chains %s" % end_of_pipe.read())