Python subprocess模块功能与常见用法实例详解


Posted in Python onJune 28, 2018

本文实例讲述了Python subprocess模块功能与常见用法。分享给大家供大家参考,具体如下:

一、简介

subprocess最早在2.4版本引入。用来生成子进程,并可以通过管道连接他们的输入/输出/错误,以及获得他们的返回值。

subprocess用来替换多个旧模块和函数:

  • os.system
  • os.spawn*
  • os.popen*
  • popen2.*
  • commands.*

运行python的时候,我们都是在创建并运行一个进程,linux中一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在python中,我们通过标准库中的subprocess包来fork一个子进程,并且运行一个外部的程序。subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所欲我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

二、旧有模块的使用

1.os.system()

执行操作系统的命令,将结果输出到屏幕,只返回命令执行状态(0:成功,非 0 : 失败)

import os
>>> a = os.system("df -Th")
Filesystem   Type  Size Used Avail Use% Mounted on
/dev/sda3   ext4  1.8T 436G 1.3T 26% /
tmpfs     tmpfs  16G   0  16G  0% /dev/shm
/dev/sda1   ext4  190M 118M  63M 66% /boot
>>> a
0     # 0 表示执行成功
# 执行错误的命令
>>> res = os.system("list")
sh: list: command not found
>>> res
32512    # 返回非 0 表示执行错误

2. os.popen()

执行操作系统的命令,会将结果保存在内存当中,可以用read()方法读取出来

import os
>>> res = os.popen("ls -l")
# 将结果保存到内存中
>>> print res
<open file 'ls -l', mode 'r' at 0x7f02d249c390>
# 用read()读取内容
>>> print res.read()
total 267508
-rw-r--r-- 1 root root  260968 Jan 27 2016 AliIM.exe
-rw-------. 1 root root   1047 May 23 2016 anaconda-ks.cfg
-rw-r--r-- 1 root root  9130958 Nov 18 2015 apache-tomcat-8.0.28.tar.gz
-rw-r--r-- 1 root root     0 Oct 31 2016 badblocks.log
drwxr-xr-x 5 root root   4096 Jul 27 2016 certs-build
drwxr-xr-x 2 root root   4096 Jul 5 16:54 Desktop
-rw-r--r-- 1 root root   2462 Apr 20 11:50 Face_24px.ico

三、subprocess模块

1、subprocess.run()

>>> import subprocess
# python 解析则传入命令的每个参数的列表
>>> subprocess.run(["df","-h"])
Filesystem      Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-LogVol00
           289G  70G 204G 26% /
tmpfs         64G   0  64G  0% /dev/shm
/dev/sda1       283M  27M 241M 11% /boot
CompletedProcess(args=['df', '-h'], returncode=0)
# 需要交给Linux shell自己解析,则:传入命令字符串,shell=True
>>> subprocess.run("df -h|grep /dev/sda1",shell=True)
/dev/sda1       283M  27M 241M 11% /boot
CompletedProcess(args='df -h|grep /dev/sda1', returncode=0)

2、subprocess.call()

执行命令,返回命令的结果和执行状态,0或者非0

>>> res = subprocess.call(["ls","-l"])
总用量 28
-rw-r--r-- 1 root root   0 6月 16 10:28 1
drwxr-xr-x 2 root root 4096 6月 22 17:48 _1748
-rw-------. 1 root root 1264 4月 28 20:51 anaconda-ks.cfg
drwxr-xr-x 2 root root 4096 5月 25 14:45 monitor
-rw-r--r-- 1 root root 13160 5月  9 13:36 npm-debug.log
# 命令执行状态
>>> res
0

3、subprocess.check_call()

执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常

>>> subprocess.check_call(["ls","-l"])
总用量 28
-rw-r--r-- 1 root root   0 6月 16 10:28 1
drwxr-xr-x 2 root root 4096 6月 22 17:48 _1748
-rw-------. 1 root root 1264 4月 28 20:51 anaconda-ks.cfg
drwxr-xr-x 2 root root 4096 5月 25 14:45 monitor
-rw-r--r-- 1 root root 13160 5月  9 13:36 npm-debug.log
0
>>> subprocess.check_call(["lm","-l"])
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/usr/lib64/python2.7/subprocess.py", line 537, in check_call
  retcode = call(*popenargs, **kwargs)
 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

4、subprocess.getstatusoutput()

接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果

#执行正确
>>> subprocess.getstatusoutput('pwd')
(0, '/root')
#执行错误
>>> subprocess.getstatusoutput('pd')
(127, '/bin/sh: pd: command not found')

5、subprocess.getoutput()

接受字符串形式的命令,放回执行结果

>>> subprocess.getoutput('pwd')
'/root'

6、subprocess.check_output()

执行命令,返回执行的结果,而不是打印

>>> res = subprocess.check_output("pwd")
>>> res
b'/root\n' # 结果以字节形式返回

四、subprocess.Popen()

其实以上subprocess使用的方法,都是对subprocess.Popen的封装,下面我们就来看看这个Popen方法。

1、stdout

标准输出

>>> res = subprocess.Popen("ls /tmp/yum.log", shell=True, stdout=subprocess.PIPE) # 使用管道
>>> res.stdout.read()  # 标准输出
b'/tmp/yum.log\n'
res.stdout.close()  # 关闭

2、stderr

标准错误

>>> import subprocess
>>> res = subprocess.Popen("lm -l",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# 标准输出为空
>>> res.stdout.read()
b''
#标准错误中有错误信息
>>> res.stderr.read()
b'/bin/sh: lm: command not found\n'

注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道,这个需要画一个图来解释一下:

Python subprocess模块功能与常见用法实例详解

4、poll()

定时检查命令有没有执行完毕,执行完毕后返回执行结果的状态,没有执行完毕返回None

>>> res = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> print(res.poll())
None
>>> print(res.poll())
None
>>> print(res.poll())
0

5、wait()

等待命令执行完成,并且返回结果状态

>>> obj = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> obj.wait()
# 中间会一直等待
0

6、terminate()

结束进程

import subprocess
>>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.terminate() # 结束进程
>>> res.stdout.read()
b''

7、pid

获取当前执行子shell的程序的进程号

import subprocess
>>> res = subprocess.Popen("sleep 5;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.pid # 获取这个linux shell 的 进程号
2778

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python求斐波那契数列示例分享
Feb 14 Python
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
Jul 12 Python
python实现分页效果
Oct 25 Python
目前最全的python的就业方向
Jun 05 Python
利用Python如何批量修改数据库执行Sql文件
Jul 29 Python
python实现车牌识别的示例代码
Aug 05 Python
python实现的config文件读写功能示例
Sep 24 Python
Python实现线性判别分析(LDA)的MATLAB方式
Dec 09 Python
python 解决flask uwsgi 获取不到全局变量的问题
Dec 22 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
Feb 17 Python
Python3爬虫里关于Splash负载均衡配置详解
Jul 10 Python
python上selenium的弹框操作实现
Jul 13 Python
对python中array.sum(axis=?)的用法介绍
Jun 28 #Python
Python3连接SQLServer、Oracle、MySql的方法
Jun 28 #Python
对Python中数组的几种使用方法总结
Jun 28 #Python
Python动态导入模块的方法实例分析
Jun 28 #Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
Jun 28 #Python
python实现将读入的多维list转为一维list的方法
Jun 28 #Python
numpy matrix和array的乘和加实例
Jun 28 #Python
You might like
初级的用php写的采集程序
2007/03/16 PHP
PHP 动态随机生成验证码类代码
2010/04/09 PHP
Yii学习总结之数据访问对象 (DAO)
2015/02/22 PHP
php封装db类连接sqlite3数据库的方法实例
2017/12/19 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
php+lottery.js实现九宫格抽奖功能
2019/07/21 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
2020/02/12 PHP
Enter回车切换输入焦点实现思路与代码兼容各大浏览器
2014/09/01 Javascript
jquery中append()与appendto()用法分析
2014/11/14 Javascript
jQuery中:hidden选择器用法实例
2014/12/30 Javascript
Js可拖拽放大的层拖动特效实现方法
2015/02/25 Javascript
js如何判断输入字符串长度
2015/12/16 Javascript
全面理解闭包机制
2016/07/11 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
Vue.js组件tree实现无限级树形菜单
2016/12/02 Javascript
解析Vue.js中的组件
2018/02/02 Javascript
angularjs获取到My97DatePicker选中的值方法
2018/10/02 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
使用JS实现鼠标放上图片进行放大离开实现缩小功能
2021/01/27 Javascript
小米5s微信跳一跳小程序python源码
2018/01/08 Python
Python使用logging模块实现打印log到指定文件的方法
2018/09/05 Python
Python脚本完成post接口测试的实例
2018/12/17 Python
python2爬取百度贴吧指定关键字和图片代码实例
2019/08/14 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
2019/11/19 Python
Python图像处理库PIL的ImageFilter模块使用介绍
2020/02/26 Python
解决django无法访问本地static文件(js,css,img)网页里js,cs都加载不了
2020/04/07 Python
Python Tornado核心及相关原理详解
2020/06/24 Python
python 模拟登录B站的示例代码
2020/12/15 Python
CSS3实现时间轴特效
2020/11/02 HTML / CSS
美国著名童装品牌:OshKosh B’gosh
2016/08/05 全球购物
YBF Beauty官网:美丽挚友,美国知名彩妆品牌
2020/11/22 全球购物
医学类导师推荐信范文
2013/11/19 职场文书
党员先锋岗事迹材料
2014/05/08 职场文书
个人债务授权委托书
2014/10/17 职场文书
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技
springboot为异步任务规划自定义线程池的实现
2022/06/14 Java/Android