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中的自定义函数学习笔记
Sep 23 Python
Python实现从脚本里运行scrapy的方法
Apr 07 Python
详解Python中__str__和__repr__方法的区别
Apr 17 Python
Python Django使用forms来实现评论功能
Aug 17 Python
Python中sort和sorted函数代码解析
Jan 25 Python
Python中反射和描述器总结
Sep 23 Python
python redis连接 有序集合去重的代码
Aug 04 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
Oct 24 Python
Python中six模块基础用法
Dec 08 Python
Python实现Keras搭建神经网络训练分类模型教程
Jun 12 Python
python录音并调用百度语音识别接口的示例
Dec 01 Python
Python图像处理库PIL详细使用说明
Apr 06 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数组函数序列之array_slice() - 在数组中根据条件取出一段值,并返回
2011/11/07 PHP
ie与session丢失(新窗口cookie丢失)实测及解决方案
2013/07/15 PHP
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
Django中的cookie与session操作实例代码
2017/08/17 PHP
php JWT在web端中的使用方法教程
2018/09/06 PHP
jquery刷新页面的实现代码(局部及全页面刷新)
2011/07/11 Javascript
表单的焦点顺序tabindex和对应enter键提交
2013/01/04 Javascript
jquery Mobile入门—多页面切换示例学习
2013/01/08 Javascript
node.js中的http.response.end方法使用说明
2014/12/14 Javascript
transport.js和jquery冲突问题的解决方法
2015/02/10 Javascript
在Node.js应用中使用Redis的方法简介
2015/06/24 Javascript
Easyui Treegrid改变默认图标的方法
2016/04/29 Javascript
微信小程序 二维码canvas绘制实例详解
2017/01/06 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
jQuery向webApi提交post json数据
2017/01/16 Javascript
Nodejs多站点切换Htpps协议详解及简单实例
2017/02/23 NodeJs
vue中的模态对话框组件实现过程
2018/05/01 Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
2019/07/12 jQuery
js实现百度登录窗口拖拽效果
2020/03/19 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
JavaScript实现移动端弹窗后禁止滚动
2020/05/25 Javascript
Electron实现应用打包、自动升级过程解析
2020/07/07 Javascript
Python3匿名函数用法示例
2018/07/25 Python
pandas筛选某列出现编码错误的解决方法
2018/11/07 Python
详解安装mitmproxy以及遇到的坑和简单用法
2019/01/21 Python
使用python获取邮箱邮件的设置方法
2019/09/20 Python
Python 实现向word(docx)中输出
2020/02/13 Python
Python sqlite3查询操作过程解析
2020/02/20 Python
jupyter notebook插入本地图片的实现
2020/04/13 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
Python实现淘宝秒杀功能的示例代码
2021/01/19 Python
施华洛世奇匈牙利官网:SWAROVSKI匈牙利
2019/07/06 全球购物
外语学院毕业生的自我鉴定
2013/11/28 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
JavaScript文档对象模型DOM
2021/11/20 Javascript
动漫APP软件排行榜前十名,半次元上榜,第一款由腾讯公司推出
2022/03/18 杂记