目錄
- 一、了解subprocess
- 1、subprocess.run()方法
- 2、Popen類
- 二、補充os模塊執行外部命令
- 1、os.system()方法
- 2、os.popen()用法
一、了解subprocess
- subeprocess模塊是python自帶的模塊,無需安裝,主要用來取代一些就的模塊或方法,如os.system、os.spawn*、os.popen、commands.*等。
- 因此執行外部命令優先使用subprocess模塊
1、subprocess.run()方法
subprocess.run()方法是官方推薦的方法,幾乎所有的工作都可以用它來完成。
如下是函數源碼:
subprocess.run(args,
*,
stdin=None,
input=None,
stdout=None,
stderr=None,
shell=False,
ced=None,
timeout=None,
check=False,
enccoding=None,
error=None)
該函數返回一個CompletedProcess類(有屬性傳入參數及返回值)的實例,該函數的參數有很多,只需要記住常用的即可
1、args : 代表需要在操作系統中執行的命令,可以是字符串形式(要求shell=True),也可以是list列表類型
2、* :代表可變參數,一般是列表或者字典類型
3、stdin、stdout、stderr :指定了可執行程序的標準輸入、標準輸出、標準錯誤文件句柄
4、shell :代表著程序是否需要在shell上執行,當想使用shell的特性時,設置shell=True,這樣就可以使用shell指令的管道、文件名稱通配符、環境變量等,不過python也提供了很多類似shell的模塊,如glob、fnmatch、os.walk()、os.path.expandvars()、os.path.expanduser()和shutil。
5、check :如果check設置為True,就檢查命令的返回值,當返回值為0時,將拋出AclledProcessError的異常
6、timeout :設置超時時間,如果超時則kill掉子進程
1.使用字符串方式執行shell命令
[root@localhost python]# vim 1.py
#!/bin/env python3
import subprocess
b=subprocess.run("ls -l /ltp | head -2", shell=True) # 執行run方法,并將返回值賦值給b
# total 184980
# -rw-r--r--. 1 root root 10865 May 8 16:21 123.txt
print(b) # 執行該run函數后返回的CompletedProcess類
# CompletedProcess(args='ls -l /ltp | head -2', returncode=0)
print(b.args) # 打印出CompletedProcess類的agrs屬性值,就是執行的shell命令
# ls -l /ltp | head -2
print(b.returncode) # 打印命令執行的狀態碼
# 0
結果展示
[root@localhost python]# ./1.py
total 184980
-rw-r--r--. 1 root root 10865 May 8 16:21 123.txt
CompletedProcess(args='ls -l /ltp | head -2', returncode=0)2
ls -l /ltp | head -2
0
2.使用列表方式執行
個人感覺方法二不好用,尤其是想要使用管道符號是,很難用
#!/bin/env python3
import subprocess
b = subprocess.run(["ls", "-l", "/ltp"])
print(b)
print(b.args)
print(b.returncode)
執行結果
[root@localhost python]# ./2.py
total 10865
-rw-r--r--. 1 root root 10865 May 8 16:21 123.txt
CompletedProcess(args=['ls', '-l', '/ltp'], returncode=0)
['ls', '-l', '/ltp']
0
3.捕獲腳本輸出
- 如果需要采集命令執行的結果,可以傳入參數stdout=subprocess.PIPE
[root@localhost python]# cat 3.py
#!/bin/env python3
import subprocess
# 傳入stdout=subprocess.PIPE參數即可
b=subprocess.run("ls -l /ltp | head -2", shell=True, stdout=subprocess.PIPE)
print(b.stdout)
結果顯示
[root@localhost python]# ./1.py
b'total 184980\n-rw-r--r--. 1 root root 10865 May 8 16:21 123.txt\n'
4.檢測異常
示例1:模擬renturncode值不為0
傳入參數check=True,當返回值不為0時,就會拋出異常
[root@localhost python]# cat 1.py
#!/bin/env python3
import subprocess
b=subprocess.run("ls -l /123 | head -2 exit 1", shell=True, stdout=subprocess.PIPE, check=True)
print(b.returncode)
執行結果:返回了CalledProcessError 類型報錯
[root@localhost python]# ./1.py
ls: cannot access /123: No such file or directory
Traceback (most recent call last):
File "./1.py", line 3, in module>
b=subprocess.run("ls -l /123 | head -2 exit 1", shell=True, stdout=subprocess.PIPE, check=True)
File "/usr/local/python3/lib/python3.7/subprocess.py", line 487, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'ls -l /123 | head -2 exit 1' returned non-zero exit status 1.
# 返回了 CalledProcessError 類型報錯
示例2:模擬執行超時
返回 TimeoutExpired 異常
[root@localhost python]# vim 1.py
#!/bin/env python3
import subprocess
b=subprocess.run("while 2>1;do sleep 1;done",timeout=3, shell=True, stdout=subprocess.PIPE, check=True)
print(b.returncode)
顯示結果
[root@localhost python]# ./1.py
Traceback (most recent call last):
File "/usr/local/python3/lib/python3.7/subprocess.py", line 474, in run
stdout, stderr = process.communicate(input, timeout=timeout)
File "/usr/local/python3/lib/python3.7/subprocess.py", line 939, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/local/python3/lib/python3.7/subprocess.py", line 1682, in _communicate
self._check_timeout(endtime, orig_timeout)
File "/usr/local/python3/lib/python3.7/subprocess.py", line 982, in _check_timeout
raise TimeoutExpired(self.args, orig_timeout)
subprocess.TimeoutExpired: Command 'while 2>1;do sleep 1;done' timed out after 3 seconds
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./1.py", line 3, in module>
b=subprocess.run("while 2>1;do sleep 1;done",timeout=3, shell=True, stdout=subprocess.PIPE, check=True)
File "/usr/local/python3/lib/python3.7/subprocess.py", line 479, in run
stderr=stderr)
subprocess.TimeoutExpired: Command 'while 2>1;do sleep 1;done' timed out after 3 seconds
2、Popen類
1.初步認識Popen類
首先來看一下Popen類的構造函數
|
class Popen(
args,
bufsize=0,
executable=None,
stdin=None,
stdout=None,
stderr=None,
preexec_fn=None,
close_fds=False,
shell=False,
cwd=None,
env=None,
universal_newlines=False,
startupinfo=None,
creationflags=0
):
參數
|
字符串或列表bufsize0 : 無緩沖
參數 |
字符串或列表 |
bufsize |
0 : 無緩沖
1 : 行緩沖
其他正數值 :緩沖區大小
負數值 :采用默認的系統緩沖(一般是全緩沖) |
executable |
一般不用,args 字符串或列表 的第一項表示程序名 |
stdin
stdout
stderr |
None : 沒有任何重定向 繼承父進程
PIPE : 創建管道
文件對象
文件描述符(整數)
stderr也可以設置為stdout |
preexec_fn |
鉤子函數,在fork和exec之間執行 |
close_fds |
unix 下執行新進程前是否關閉0/1/2之外的文件
windows 下不繼承還是繼承父進程的文件描述 |
shell |
若為True的話 :
在unix 下相當于在args前面添加了 “/bin/bash” “-c"
在windows下,相當于添加了"cmd.exe /c” |
cwd |
設置工作目錄 |
env |
設置環境變量 |
unviersal_newlines |
各種換行符統一處理成"\n" |
startupinfo |
windows下傳遞給CreateProcess的結構體 |
creationflags |
windows下,傳遞CREATE_NEW_CONSOLE創建自己的控制臺窗口 |
2.Popen的使用方法
1、subprocess.Popen([“cat”, “abc.txt”])
2、subprocess.Popen(“cat abc.txt”, shell=True)
上面的第二種其實就相當于:subprocess.Popen(["/bin/bash", “-c”, “cat abc.txt”])
示例:
[root@localhost python]# cat 3.py
#!/bin/env python3
import subprocess
obj = subprocess.Popen("ls -l /ltp",
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
error_info = obj.stderr.read()
out_info = obj.stdout.read()
result = out_info + error_info
print(result)
[root@localhost python]# ./3.py
total 184980
-rw-r--r--. 1 root root 10865 May 8 16:21 123.txt
-rw-r--r--. 1 root root 802 Apr 21 09:42 ab.sh
drwxr-xr-x. 3 root root 101 Apr 1 18:34 auth
-rw-r--r--. 1 root root 5242880 Mar 18 13:20 bigfile
-rwxrwxrwx. 1 root root 1392 Feb 5 09:24 dingding.sh
Popen類的對象方法
名稱 |
功能 |
poll() |
檢查是否結束,設置返回值 |
wait() |
等待結束,設置返回值 |
communicate() |
參數是標準輸入,返回標準輸出和標準出錯 |
send_signal() |
發動信號(主要指linux下有用) |
terminate() |
終止進程,unix對應的SIGTERM信號,windows下調用api函數TerminateProcess() |
kill() |
殺死進程(unix對應SIGKILL信號),windows下同上 |
stdin
stdout
stderr |
參數中指定PIPE時有用 |
pid |
進程id |
returncode |
進程返回值 |
補充:其他方法
1、subeprocess.call(*args,**kwargs): call()方法調用Popen()執行程序,并且等待它執行完成
2、subpeocess.check_call(*args, **kwargs): 調用上面的call(),如果返回值非零,返回異常
3、subprocess.check_output(*args, **kwargs) : 調用Popen()執行程序,并返回標準輸出
二、補充os模塊執行外部命令
1、os.system()方法
示例:
[root@localhost python]# cat 4.py
#!/bin/env python3
import os
# 變量ret接收命令執行后的返回值
ret = os.system('ls -l /ltp |head -2')
print("\n執行成功" if ret == 0 else "\n執行失敗")
執行結果
[root@localhost python]# ./4.py
total 184980
-rw-r--r--. 1 root root 10865 May 8 16:21 123.txt
執行成功
2、os.popen()用法
與subprocess.Popen()類似,就不寫了
補充:subprocess.run()和subprocess.Popen()的執行結果是寫入到緩存的,可以執行結束后打印結果,不會實時在終端輸出;而os.system()是實時輸出到終端界面的;
以上就是Python執行外部命令subprocess的詳細內容,更多關于Python執行外部命令的資料請關注腳本之家其它相關文章!
您可能感興趣的文章:- Python實現subprocess執行外部命令
- Python中使用subprocess庫創建附加進程
- 解決python subprocess參數shell=True踩到的坑
- python3通過subprocess模塊調用腳本并和腳本交互的操作
- python subprocess pipe 實時輸出日志的操作
- 通過實例解析python subprocess模塊原理及用法
- 解決windows下python3使用multiprocessing.Pool出現的問題
- Python多進程multiprocessing、進程池用法實例分析
- 使用python執行shell腳本 并動態傳參 及subprocess的使用詳解
- python process模塊的使用簡介