[TOC]
## 模塊說明
subprocess是Python 2.4中新增的一個模塊提供了一個更高級的接口。用于替換和系統交互的os.system() , os.spawnv()等.
在Python 3.5之后,官方提倡通過subprocess.run()函數替代其他函數來使用subproccess模塊的功能; ?
在Python 3.5之前的版本中,我們可以通過subprocess的call()、getoutput()等函數來使用subprocess模塊的功能;
run()、call()、check_call()和check_output()都是通過對Popen的封裝來實現的高級函數,因此如果我們需要更復雜功能時,可以通過subprocess.Popen來完成。
### 常用函數語法
* run函數
3.5中新增。執行指定的命令,等待命令執行完成后返回一個包含執行結果的CompletedProcess類的實例。
```
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)
```
* call函數
執行指定的命令,返回命令執行狀態,其功能類似于os.system(cmd)
```
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
```
* check_call函數
2.5中新增。 執行指定的命令,如果執行成功則返回狀態碼,否則拋出異常。等價于`subprocess.run(..., check=True)`
```
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
```
* check_output函數
2.7中新增。執行指定的命令,如果執行狀態碼為0則返回命令執行結果,否則拋出異常。
```
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)
```
* getstatusoutput、getoutput函數
```
subprocess.getstatusoutput(cmd)
subprocess.getoutput(cmd)
```
* Popen方法[底層方法]
```
subprocess.Popen()
```
### 參數說明
* args:
要執行的shell命令,默認是一個字符串序列,如['df', '-Th']或('df', '-Th'),也可以是一個字符串,如'df -Th',但需要shell參數的值為True。?
* shell:
如果shell為True,那么指定的命令將通過shell執行。在命令中有管道、通配符、環境變量等時非常有用。
* check:
如果check參數的值是True,且執行命令的進程以非0狀態碼退出,則會拋出一個CalledProcessError的異常,包含 參數、退出狀態碼、以及stdout和stderr?
* stdout, stderr:
run()函數默認不會捕獲命令執行結果的正常輸出和錯誤輸出而直接返回到屏幕,如果要捕獲需要通過`stdout=subprocess.PIPE`來捕獲,然后用CompletedProcess類實例的stdout和stderr屬性來輸出的內容
>call()和check_call()函數返回的是命令執行的狀態碼,對于它們而言,stdout和stderr不適合賦值為subprocess.PIPE;?
check_output()函數默認就會返回命令執行結果,所以只需在捕獲錯誤信息時,執行stderr=subprocess.STDOUT?
* input:
該參數是傳遞給Popen.communicate(),通常該參數的值必須是一個字節列表,如果universal_newlines=True,則其值應該是一個字符串。?
* universal_newlines:
該參數影響的是輸入與輸出的數據格式,比如它的值默認為False,此時stdout和stderr的輸出是字節序列;當該參數的值設置為True時,stdout和stderr的輸出是字符串。
### subprocess.CompletedProcess類介紹
run()函數是Python3.5中新增的一個高級函數,其返回值是一個CompletedPorcess類的實例,completedPorcess類也是Python 3.5中才存在的。
它表示的是一個已結束進程的狀態信息,它所包含的屬性如下:
* args:
用于加載該進程的參數,這可能是一個列表或一個字符串?
* returncode:
子進程的退出狀態碼。0成功,非0失敗;負值-N表示這個子進程被信號N終止了?
* stdout:
從子進程捕獲的stdout。這通常是一個字節序列
* stderr:
從子進程捕獲的stderr,字節列表。如果stderr未被捕獲的話,為None?
* check_returncode():
如果returncode是一個非0值,則該方法會拋出一個CalledProcessError異常。
## `run()`方法舉例
### 1.常見寫法
默認run方法是將命令結果直接輸出,而不存儲,自身只存儲`CompletedProcess`方法
```
>>> subprocess.run(['free','-h'])
>>> subprocess.run('free -h',shell=True)
>>> a=subprocess.run(['free','-h'],shell=True)
total used free shared buff/cache available
Mem: 2017280 1053132 231080 6772 733068 748920
Swap: 998396 12544 985852
>>> a
CompletedProcess(args=['free', '-h'], returncode=0)
```
### 獲取返回結果
如果想要捕獲命令執行的結果和錯誤供其他時候調用,需要通過python的管道捕獲,如下
*?stdout=subprocess.PIPE 命令執行成功返回的內容
*?stderr=subprocess.PIPE 命令執行錯誤返回的錯誤內容
```
>>> a=subprocess.run(['free','-h'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> a.stdout.decode() # 如果命令執行正確,此方法就讀出程序結果
>>> a.stderr.decode() # 如果命令執行錯誤,此方法就讀出報錯信息
```
>因為執行一條命令就會打開一個進程,進程間數據不能通信,所以需要先將結果賦予stdout、stderr的,再傳給程序
### 遇到錯誤停止
subprocess.run()方法執行命令時,如果命令是錯的,程序不會報錯而繼續運行,如果要命令錯的時候程序報錯停止運行的話,可以加個check參數
```
>>> subprocess.run('free -sh',shell=True,check=True)
>>> a=subprocess.run(['free','-h'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
```
>check參數設置為True的時候就會檢查命令是否是錯的
## 除popen外其他方法
### call方法
call方法會將結果直接輸出,自身自獲取命令執行狀態,0 or 非0
```
>>> b=subprocess.call('ls /dev/null',shell=True)
/dev/null
>>> b
0
```
### check_call方法
check_call方法是如果命令正常執行就返回狀態碼0,否則拋異常
```
>>> b=subprocess.check_call('ls /dev/null',shell=True)
/dev/null
>>> b
0
```
### check_output方法
check_output執行命令,如果正常執行則并結果,否則拋出異常
```
>>> subprocess.check_output('ls /dev/null',shell=True)
b'/dev/null\n'
>>> b=subprocess.check_output('ls /dev/null',shell=True)
>>> b
b'/dev/null\n'
```
### getoutput和getstatusoutput方法
getoutput和getstatusoutput函數是Python 2.x的commands模塊的遺留函數。 隱式的調用系統shell,不保證其他函數所具有的安全性和異常處理的一致性。且3.3.4開始才支持Windows平臺。
* getstatusoutput方法
接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果
```
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
```
* getoutput方法
接收字符串格式命令,并返回結果
```
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'
```
## `Popen()`方法詳解
函數call(), check_call() 和 check_output() 都是Popen類的包裝器。直接使用Popen會對如何運行命令以及如何處理其輸入輸出有更多控制。如通過為stdin, stdout和stderr傳遞不同的參數。
### 常用參數:
* args:
shell命令,可以是字符串或者序列類型(如:list,元組)
* stdin, stdout, stderr:
分別表示程序的標準輸入,標準輸出及標準錯誤
* preexec_fn:
只在Unix平臺下有效,用于指定一個可執行對象,它將在子進程運行之前被調用
* shell:
與其他方法中用法相同
* cwd:
用于設置子進程的當前目錄
* env:
用于指定子進程的環境變量。如果env=None,則默認從父進程繼承環境變量
universal_newlines:不同系統的的換行符不同,當該參數設定為true時,則表示使用`\n`作為換行符
### Popen的方法
Popen和run區別是,run會在當前界面等待命令執行完成,Popen執行后后立刻返回一個對象,而不等命令執行結果。
```
a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)
a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)`
```
**Popen返回的對象有以下方法**
* Popen.poll()
檢查子進程是否已終止,設置并返回returncode屬性
* Popen.wait (timeout=None)
等待子進程終止,設置并返回returncode屬性
* Popen.communicate()
與啟動的子進程交互,發送數據到stdin,并從stdout接收輸出,然后等待任務結束
* Popen.pid ()
返回子進程ID
* Popen.returncode ()
返回子進程的狀態碼.
* Popen.terminate()
停止子進程
* Popen.kill()
殺死子進程
* Popen.send_signal()
向子進程發送信號
* Popen.args ()
傳遞給Popen的參數,可以是列表 或者 字符串
* Popen.stdin()/stdout()/stderr()
如果stdin/stdout/stderr 參數是PIPE,返回可寫流對象,如果指定encoding等參數為True,怎是文本流,否則字節流,如果stdin的參數不是PIPE,返回None
### 操作舉例
* 查看pid和返回值等
```python
>>> aa=subprocess.Popen('for i in `seq 5`;do echo "$i";done',stdout=subprocess.PIPE,shell=True)
>>> aa.pid
44695
>>> aa.poll()
0
>>> aa.communicate()
(b'1\n2\n3\n4\n5\n', None)
```
* 輸出結果定向到標準輸出供其他程序使用
```python
>>> aa=subprocess.Popen('cat /etc/passwd',stdout=subprocess.PIPE,shell=True)
>>> subprocess.Popen('grep root',stdin=aa.stdout,shell=True)
<subprocess.Popen object at 0x7f4d3072d1d0>
root:x:0:0:root:/root:/bin/bash
```
- 基礎部分
- 基礎知識
- 變量
- 數據類型
- 數字與布爾詳解
- 列表詳解list
- 字符串詳解str
- 元組詳解tup
- 字典詳解dict
- 集合詳解set
- 運算符
- 流程控制與循環
- 字符編碼
- 編的小程序
- 三級菜單
- 斐波那契數列
- 漢諾塔
- 文件操作
- 函數相關
- 函數基礎知識
- 函數進階知識
- lambda與map-filter-reduce
- 裝飾器知識
- 生成器和迭代器
- 琢磨的小技巧
- 通過operator函數將字符串轉換回運算符
- 目錄規范
- 異常處理
- 常用模塊
- 模塊和包相關概念
- 絕對導入&相對導入
- pip使用第三方源
- time&datetime模塊
- random隨機數模塊
- os 系統交互模塊
- sys系統模塊
- shutil復制&打包模塊
- json&pickle&shelve模塊
- xml序列化模塊
- configparser配置模塊
- hashlib哈希模塊
- subprocess命令模塊
- 日志logging模塊基礎
- 日志logging模塊進階
- 日志重復輸出問題
- re正則表達式模塊
- struct字節處理模塊
- abc抽象類與多態模塊
- requests與urllib網絡訪問模塊
- 參數控制模塊1-optparse-過時
- 參數控制模塊2-argparse
- pymysql數據庫模塊
- requests網絡請求模塊
- 面向對象
- 面向對象相關概念
- 類與對象基礎操作
- 繼承-派生和組合
- 抽象類與接口
- 多態與鴨子類型
- 封裝-隱藏與擴展性
- 綁定方法與非綁定方法
- 反射-字符串映射屬性
- 類相關內置方法
- 元類自定義及單例模式
- 面向對象的軟件開發
- 網絡-并發編程
- 網絡編程SOCKET
- socket簡介和入門
- socket代碼實例
- 粘包及粘包解決辦法
- 基于UDP協議的socket
- 文件傳輸程序實戰
- socketserver并發模塊
- 多進程multiprocessing模塊
- 進程理論知識
- 多進程與守護進程
- 鎖-信號量-事件
- 隊列與生產消費模型
- 進程池Pool
- 多線程threading模塊
- 進程理論和GIL鎖
- 死鎖與遞歸鎖
- 多線程與守護線程
- 定時器-條件-隊列
- 線程池與進程池(新方法)
- 協程與IO模型
- 協程理論知識
- gevent與greenlet模塊
- 5種網絡IO模型
- 非阻塞與多路復用IO實現
- 帶著目標學python
- Pycharm基本使用
- 爬蟲
- 案例-爬mzitu美女
- 案例-爬小說
- beautifulsoup解析模塊
- etree中的xpath解析模塊
- 反爬對抗-普通驗證碼
- 反爬對抗-session登錄
- 反爬對抗-代理池
- 爬蟲技巧-線程池
- 爬蟲對抗-圖片懶加載
- selenium瀏覽器模擬