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上基于Markov链生成伪随机文本的教程
Apr 17 Python
Python中正则表达式详解
May 17 Python
Python书单 不将就
Jul 11 Python
解决django中ModelForm多表单组合的问题
Jul 18 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
Jul 19 Python
django 类视图的使用方法详解
Jul 24 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
python操作openpyxl导出Excel 设置单元格格式及合并处理代码实例
Aug 27 Python
django创建简单的页面响应实例教程
Sep 06 Python
基于Tensorflow一维卷积用法详解
May 22 Python
python基于turtle绘制几何图形
Jun 15 Python
python编程实现清理微信重复缓存文件
Nov 01 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中的mb_detect_encoding函数使用方法
2015/08/18 PHP
php常量详细解析
2015/10/27 PHP
PHP 中提示undefined index如何解决(多种方法)
2016/03/16 PHP
JavaScript获得选中文本内容的方法
2008/12/02 Javascript
Javascript Object.extend
2010/05/18 Javascript
鼠标放在图片上显示大图的JS代码
2013/03/26 Javascript
js获取键盘按键响应事件(兼容各浏览器)
2013/05/16 Javascript
Jquery 的outerHeight方法使用介绍
2013/09/11 Javascript
nodejs npm package.json中文文档
2014/09/04 NodeJs
JS+CSS实现模仿浏览器网页字符查找功能的方法
2015/02/26 Javascript
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
深入理解JavaScript编程中的同步与异步机制
2015/06/24 Javascript
javascript中mouseover、mouseout使用详解
2015/07/19 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
2015/11/06 Javascript
基于Vue.js实现数字拼图游戏
2016/08/02 Javascript
js实现轮播图的两种方式(构造函数、面向对象)
2017/09/30 Javascript
JavaScript数组去重算法实例小结
2018/05/07 Javascript
vue2.0移动端滑动事件vue-touch的实例代码
2018/11/27 Javascript
JavaScript时间日期操作实例小结【5个示例】
2018/12/22 Javascript
Bootstrap实现模态框效果
2019/09/30 Javascript
浅析JavaScript 函数柯里化
2020/09/08 Javascript
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
Python编程求质数实例代码
2018/01/31 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
2018/05/30 Python
如何使用Python脚本实现文件拷贝
2019/11/20 Python
python pandas dataframe 去重函数的具体使用
2020/07/20 Python
python 爬取腾讯视频评论的实现步骤
2021/02/18 Python
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
俄罗斯药房连锁店:ASNA
2020/06/20 全球购物
酒店管理求职信范文
2014/04/06 职场文书
应届大专生自荐书
2014/06/16 职场文书
单位授权委托书范文
2014/08/02 职场文书
为什么MySQL不建议使用SELECT *
2022/04/03 MySQL
Python简易开发之制作计算器
2022/04/28 Python