Python执行外部命令subprocess的使用详解
作者:知无涯学无尽 发布时间:2023-01-21 14:57:49
一、了解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.txtCompletedProcess(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 secondsDuring 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()是实时输出到终端界面的;
来源:https://blog.csdn.net/CN_LiTianpeng/article/details/116736321


猜你喜欢
- 下面先来看看例子:table表字段1 字段2 i
- 本文主要介绍了Python pandas 重命名索引和列名称的实现,分享给大家,具体如下:df=pd.DataFrame(np.arange
- 引言在已有的网站中,几乎所有的网站都已经实现了 自动登录所谓自动登录,其实就是在你登录后,然后关闭浏览器,接着再启动浏览器重新进入刚刚的网站
- 本文实例讲述了Python图像处理之图像的缩放、旋转与翻转实现方法。分享给大家供大家参考,具体如下:图像的几何变换,如缩放、旋转和翻转等,在
- Python中有许多方便的库可以用来进行数据处理,尤其是Numpy和Pandas,再搭配matplot画图专用模块,功能十分强大。CSV(C
- 一、Tornado简介Tornado 是 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 We
- 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError、Unicode
- MS SQL数据库日志压缩方法 MS SQL性能是很不错的,但是数据库用了一段时间之后,数据库却变得很大,实际的数据量不
- 用python来自动生成excel数据文件。python处理excel文件主要是第三方模块库xlrd、xlwt、xluntils和pyExc
- 在windows下用python脚本实现文件的备份,参考《A Byte of Python3》第十一章(Page59)。#!/usr/bin
- 前面我们讲了一些Dreamweaver MX的基本操作,相信大家看了后都会觉得比较简单,的确,这是个工具软件,操作方便应该是它的宗旨。其实网
- urllib包和http包都是面向HTTP协议的。其中urllib主要用于处理 URL,使用urllib操作URL可以像使用和打开本地文件一
- 目录技术背景python对Excel表格的处理vaex的安装与使用vaex的安装性能对比数据格式转换总结概要技术背景数据处理是一个当下非常热
- 本文所述实例可以实现基于Python的查看图片报纸《参考消息》并将当天的图片报纸自动下载到本地供查看的功能,具体实现代码如下:# codin
- eval是Python的一个内置函数,功能十分强大,这个函数的作用是,返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值
- 安装方法1)、apt-ge安装sudo apt-get install Flask-SQLAlchemy2)、下载安装包进行安装# 安装后可
- 前序There should be one - and preferably only one - obvious way to do it
- 此次主要介绍介绍在flask框架中如何集成swagger文档, 我们知道以前给同事提供接口文档主要是写一个文档, 当遇到频繁修改
- 来与大家分享。稍加改造就可以实现更强大的功能了。用下面的代码就可以简单的批量导出picasa相册的外链了。代码如下:<%@LANGUA
- 在所有信息技术领域,网页设计、网站设计长期是个几乎搞不清楚的、弱势的、被边缘化的职能职位。但近些年发展中,不断有远见卓识的从业者认识到,“设