python第11次課

關於datetime/time/commands模塊的內容能夠點擊python內置模塊查看。html

subprocess

subprocess模塊用來生成子進程,並能夠經過管道鏈接它們的輸入/輸出/錯誤,以及得到它們的返回值。python

getoutput(cmd)

該命令相似commands模塊中的getoutput(),執行cmd命令返回執行結果。
 android

1
2
3
4
5
6
7
>>> PIDS = subprocess.getoutput("netstat -aon | findstr 0:80")
>>> print(PIDS)
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4
>>> PIDS1 = subprocess.getoutput("netstat -aon | grep 0:80")
>>> print(PIDS1)
'grep' 不是內部或外部命令,也不是可運行的程序
或批處理文件。

 

getstatusoutput(cmd)

該命令相似commands模塊中的getstatusoutput(),執行cmd命令返回包含2個元素的元組。
第一個元素爲命令執行狀態(int),若是執行成功返回0,不成功返回非0。
第二個元素爲命令執行結果(str)。shell

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import subprocess
>>> PIDS = subprocess.getstatusoutput("netstat -aon | findstr 0:80")
>>> print(PIDS)  #輸出結果爲元組
(0, '  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4\n  TCP    192.168.0.102:64793    111.202.100.60:80      TIME_WAIT       0')
>>> PIDS1 = subprocess.getstatusoutput("netstat -aon | grep 0:80")
>>> print(PIDS1)
(255, "'grep' 不是內部或外部命令,也不是可運行的程序\n或批處理文件。")
>>> status, result = subprocess.getstatusoutput("netstat -aon | grep 0:80")    #python中典型使用方法
>>> print(status)
255
>>> print(result)
'grep' 不是內部或外部命令,也不是可運行的程序
或批處理文件。

 

call()

參數說明python2.7

1
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

 

執行命令並返回執行狀態,其中shell參數爲False時,命令須要以列表的方式傳入,當shell爲True時,可直接傳入命令。默認狀況下shell=False
shell=False狀況函數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> import subprocess
>>> a = subprocess.call("ls")    #單個不帶參數的命令可直接執行
anaconda-ks.cfg
>>> print(a)    #命令執行結果
0
>>> b = subprocess.call("ls -l")    #帶參數命令直接傳入將會報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
>>> b = subprocess.call(["ls", "-l"])    #帶參數命令以列表方式傳入
total 4
-rw-------. 1 root root 2523 Apr 21  2016 anaconda-ks.cfg
>>> print(b)
0

 

shell=True狀況ui

1
2
3
4
5
6
>>> import subprocess
>>> a = subprocess.call("ls -l", shell=True)    #帶參數命令也可直接傳入
total 4
-rw-------. 1 root root 2523 Apr 21  2016 anaconda-ks.cfg
>>> print(a)
0

 

check_call()

參數說明spa

1
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

 

執行命令,若返回狀態碼爲0,則返回0,不然拋出異常CalledProcessError
注意:該方法等價於python3.5中的run(..., check=True)code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import subprocess
>>> a = subprocess.check_call(["ls", "-l"])
total 4
-rw-------. 1 root root 2523 Apr 21  2016 anaconda-ks.cfg
>>> print(a)
0
>>> a = subprocess.check_call("ls -l", shell=True)
total 4
-rw-------. 1 root root 2523 Apr 21  2016 anaconda-ks.cfg
>>> print(a)
0
>>> b = subprocess.check_call("exit 1", shell=True)    #即便正確執行命令,但返回值不爲0拋出異常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/subprocess.py", line 542, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

 

check_output()

語法說明htm

1
args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None

 

執行命令,若返回狀態碼爲0,則返回執行結果,不然拋出異常CalledProcessError
注意:該方法等價於python3.5中的run(..., check=True, stdout=PIPE).stdout

1
2
3
4
5
6
7
8
9
10
11
12
>>> import subprocess
>>> a = subprocess.check_output("ls -l", shell=True)
>>> print(a)    #輸出爲執行結果
total 4
-rw-------. 1 root root 2523 Apr 21  2016 anaconda-ks.cfg

>>> b = subprocess.check_output("exit 1", shell=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/subprocess.py", line 575, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

 

run()

python 3.5添加的函數。
語法說明:

1
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)

 

執行指定命令,等待命令執行完成後返回一個包含執行結果的CompleteProcess類的實例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> subprocess.run("dir", shell=True)
 驅動器 C 中的卷沒有標籤。
 卷的序列號是 A001-9D89

 C:\Users\xiaohuihui 的目錄

2018/04/19  20:30    <DIR>          .
2018/04/19  20:30    <DIR>          ..
2017/11/17  10:16    <DIR>          .android
............................................
...........................................
2018/01/23  16:23                 0 2.txt
2018/04/16  06:45    <DIR>          3D Objects
2018/04/13  20:28                 4 bacon.txt
               8 個文件  1,029,964,132 字節
              24 個目錄 94,803,804,160 可用字節
CompletedProcess(args='dir', returncode=0)
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\xiaohuihui\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1.
>>> subprocess.run("netstat -aon|findstr 0:80", shell=True, stdout=subprocess.PIPE)
CompletedProcess(args='netstat -aon|findstr 0:80', returncode=0, stdout=b'  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4\r\n')

 

參數說明

subprocess中的call()check_call()check_output()以及run()參數列表已經列出,下面是參數的說明

  • args
    要執行的shell命令,默認是一個字符串序列,如['df', '-hT']('df', '-hT'),也能夠是一個字符串,如'df -hT',但此時須要把shell參數的值設置爲True
  • shell
    若是shell爲True,那麼指定的命令將經過shell執行。若是須要訪問某些shell特性,如管道、文件名通配符等,這將很是有用。
  • check
    若是check參數的值是True,且執行命令的進程以非0的狀態碼退出,則會拋出一個CalledProcessError異常,且該異常對象會包含參數、退出狀態碼以及stdout和stderr(若被捕獲)。
  • stdout/stderr
    程序的標準輸出和錯誤輸出。
  • run()函數默認不會捕獲命令執行結果的正常輸出和錯誤輸出,若是咱們想獲取這些內容,須要傳遞subprocess.PIPE而後能夠經過返回的CompleteProcess類實例的stddout和stderr屬性捕獲相應的內容。
  • call()和check_call()函數返回的是命令執行的狀態碼而不是CompleteProcess類實例,因此它們的stdout和stderr不適合賦值爲subprocess.PIPE
  • check_output()函數默認會返回執行結果,因此不用設置stdout的值,若是但願在結果中捕獲錯誤信息,能夠設置stderr = subprocess.STDOUT
  • cwd
    用於設置子進程的當前目錄。當它不爲None時,子程序在執行前,它的當前路徑會被替換成cwd的值。這個路徑並不會被添加到可執行程序的搜索路徑,因此cwd不能是相對路徑。
  • input
    該參數是傳遞給Popen.communicate(),一般該參數的值必須是一個字節序列,若是universal_newline=True,則其值應該是一個字符串。
  • universal_newline
    該參數影響的是輸入輸出的數據格式,默認爲False,此時stdout和stderr的輸出是字節序列,設置爲True時stdout和stderr的輸出是字符串。

CompleteProcess類說明

subprocess.CompleteProcess類在python3.5中才存在,表示一個已經結束進程的狀態信息,包含的屬性以下

  • args:用於加載進程的參數,多是一個列表或者一個字符串。
  • returncode:子進程的退出狀態碼,一般狀況下狀態碼爲0表示進程成功運行;負值-N表示子進程被信號N終止。
  • stdout:從子進程捕獲的stdout。這一般是一個字節序列,若是run()函數被調用時指定universal_newlines=True,則該屬性值是一個字符串。若是run()函數被調用時指定stderr=subprocess.STDOUT,那麼stdout和stderr將會被整合到這一個屬性中,且stderr將會爲None
  • stderr:從子進程捕獲的stderr。它的值與stdout同樣,是一個字節序列或一個字符串。若是stderr沒有被捕獲的話,它的值就爲None
  • check_returncode(): 若是returncode是一個非0值,則該方法會拋出一個CalledProcessError異常。

Popen

該類用於在一個新的進程中執行一個子程序。上面介紹的函數都是基於subprocess.Popen類實現的,經過使用這些被封裝後的高級函數能夠很方便的完成一些常見的需求。當沒法經過上面的高級函數實現一些不太經常使用的功能時,能夠經過subprocess.Popen來完成。
示例1

1
2
3
4
>>> import subprocess
>>> p = subprocess.Popen("netstat -aon|findstr 0:80", shell=True, stdout=subprocess.PIPE)
>>> print(p.stdout.read())
b'  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4\r\n'

 

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
>>> obj.stdin.write('print(1) \n')    #返回寫入的字符數
10
>>> obj.stdin.write('print(2) \n')
10
>>> obj.stdin.write('print(3) \n')
10
>>> out,err = obj.communicate()
>>> print(out)
1
2
3

>>> print(err)

 

總結

  1. Python2.4版本引入了subprocess模塊用來替換os.system()、os.popen()、os.spawn*()等函數以及commands模塊;也就是說若是你使用的是Python 2.4及以上的版本就應該使用subprocess模塊了。
  2. 若是你的應用使用的Python 2.4以上,可是是Python 3.5如下的版本,Python官方給出的建議是使用subprocess.call()函數。Python 2.5中新增了一個subprocess.check_call()函數,Python 2.7中新增了一個subprocess.check_output()函數,這兩個函數也能夠按照需求進行使用。
  3. 若是你的應用使用的是Python 3.5及以上的版本,Python官方給出的建議是儘可能使用subprocess.run()函數。
  4. 當subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()這些高級函數沒法知足需求時,咱們可使用subprocess.Popen類來實現咱們須要的複雜功能。

更多關於subprocess說明可點擊查看官方文檔。

log

sys

os

相關文章
相關標籤/搜索