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中无限元素列表的实现方法
Aug 18 Python
python使用两种发邮件的方式smtp和outlook示例
Jun 02 Python
Python基于回溯法解决01背包问题实例
Dec 06 Python
python求质数的3种方法
Sep 28 Python
对python requests的content和text方法的区别详解
Oct 11 Python
对Python中DataFrame选择某列值为XX的行实例详解
Jan 29 Python
Python3模拟curl发送post请求操作示例
May 03 Python
简单了解python gevent 协程使用及作用
Jul 22 Python
Django实现发送邮件找回密码功能
Aug 12 Python
如何基于Python实现电子邮件的发送
Dec 16 Python
python虚拟环境模块venv使用及示例
Mar 04 Python
Python flask框架端口失效解决方案
Jun 04 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 session会话的安全性分析
2011/09/08 PHP
PHP5.5在windows安装使用memcached服务端的方法
2014/04/16 PHP
php中使用PHPExcel读写excel(xls)文件的方法
2014/09/15 PHP
php ajax实现文件上传进度条
2016/03/29 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
PHP Laravel 上传图片、文件等类封装
2017/08/16 PHP
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
JQuery 表单中textarea字数限制实现代码
2009/12/07 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
JavaScript将字符串转换成字符编码列表的方法
2015/03/19 Javascript
jquery仿百度经验滑动切换浏览效果
2015/04/14 Javascript
js/jquery判断浏览器类型的方法小结
2015/05/12 Javascript
JQuery中DOM实现事件移除的方法
2015/06/13 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
基于vue实现swipe轮播组件实例代码
2017/05/24 Javascript
JavaScript实现AOP详解(面向切面编程,装饰者模式)
2017/12/19 Javascript
vue.js实现只弹一次弹框
2018/01/29 Javascript
Vuex mutitons和actions初使用详解
2019/03/04 Javascript
微信小程序textarea层级过高的解决方法
2019/03/04 Javascript
使用vscode快速建立vue模板过程详解
2019/10/10 Javascript
[07:43]《辉夜杯》公开赛晋级外卡赛战队—TRG训练生活探秘
2015/12/11 DOTA
[02:42]DOTA2城市挑战赛收官在即 四强之争风起云涌
2018/06/05 DOTA
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python get获取页面cookie代码实例
2018/09/12 Python
python批量从es取数据的方法(文档数超过10000)
2018/12/27 Python
django-filter和普通查询的例子
2019/08/12 Python
Django密码存储策略分析
2020/01/09 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
CSS3控制HTML元素动画效果
2014/02/08 HTML / CSS
《争吵》教学反思
2014/02/15 职场文书
机械专业求职信范文
2014/07/15 职场文书
雷锋的故事观后感
2015/06/10 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书
深入解析NumPy中的Broadcasting广播机制
2021/05/30 Python