python3中使用subprocess模块执行外部命令
一. subprocess模块介绍
subprocess模块可以替代os模块下的os.system和os.popen等操作方法
subprocess模块在python2和python3上的使用上有一定的区别,本文主要介绍的是在python3.6上的使用
subprocess模块的作用是执行外部命令(支持同步执行和异步执行),可以返回执行状态码,也可以返回执行内容
subprocess模块的方法有很多,最核心的方法为subprocess.Popen方法,python3中如果只需要同步执行,优先使用subprocess.run方法
二. subprocess.run()方法的介绍
2.1 执行代码:在windows下执行一条cmd命令
# -*- coding:utf-8 -*-
# Author:chinablueimport subprocess# 在windows下执行cmd命令:echo hello dj
p = subprocess.run("echo hello dj", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f'获取返回对象: {p}')
print(f'获取执行命令:{p.args}')
print(f'获取返回码:{p.returncode}')
print(f'获取返回数据:{p.stdout}')
2.2 执行结果:
获取返回对象: CompletedProcess(args='echo hello dj', returncode=0, stdout=b'hello dj\r\n', stderr=b'')
获取执行命令:echo hello dj
获取返回码:0
获取返回数据:b'hello dj\r\n'
2.3 分析小结:
1 ) subprocess.run()方法是一个同步方法,执行后会返回一个CompletedProcess对象
2 ) 通过管道可以捕获子进程的标准输出(stdout)和标准错误(stderr)
如果使用的是python3.7及以上版本,可以使用capture_output=True参数替换stdout=subprocess.PIPE和stderr=subprocess.PIPE参数
p = subprocess.run("echo hello dj", shell=True, capture_output=True)
print(f'获取返回数据:{p.stdout}')
# 执行结果:获取返回数据:b'hello dj\r\n'
将执行结果输出到一个文件中去
# 将命令的执行结果输出到output.txt文件中
# 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
# 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
with open("output.txt", "w") as f:p1 = subprocess.run("dir", shell=True, stdout=f, universal_newlines=True, encoding="utf-8")
3 ) 默认情况下,获取的返回数据(stdxxx)为字节类型。
通过universal_newlines=True
参数可以让返回数据以文本字符串输出
p = subprocess.run("echo hello dj", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
print(f'获取返回数据:{p.stdout}')
# 运行结果:获取返回数据:hello dj
如果使用的是python3.7及以上版本, 可以使用text=True参数替换universal_newlines=True
参数
p = subprocess.run("echo hello dj", shell=True, capture_output=True, text=True)
print(f'获取返回数据:{p.stdout}')
# 运行结果:获取返回数据:hello dj
如果不使用universal_newlines=True
参数或text=True参数,我们也可以对p.stdout进行解码转换
p = subprocess.run("echo hello dj", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f'获取返回数据:{p.stdout.decode("gbk")}') # 注意:windows下需要使用gbk解码
# 运行结果:获取返回数据:hello dj
4 ) 关于返回状态码的说明
如果命令执行成功,returncode返回0; 如果命令执行失败,returncode返回负值
check=True参数会自动检查p.returncode
是否返回0, 如果不是0就抛出subprocess.CalledProcessError
异常
p = subprocess.run("echo1", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
print(f'获取返回数据:{p.stdout}')
如果不使用 check=True参数,我们可以通过p.returncode来做判断条件, 进而打印出详细错误p.stderr
# 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
# 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
p = subprocess.run("echo1", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
if p.returncode !=0:print(f'命令执行失败:{p.stderr}')
三. subprocess.Popen()方法的介绍
subprocess.run()是通过subprocess.Popen()来实现的
subprocess.Popen()可以异步执行
3.1 执行代码:在windows下执行一条cmd命令
# -*- coding:utf-8 -*-
# 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
# 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!import subprocess# 在windows下执行cmd命令:echo chinablue
p = subprocess.Popen("echo chinablue", shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
print(f"获取返回对象: {p}")
print(f"获取pid: {p.pid}")
print(f"获取返回数据: {p.stdout.read()}")
p.wait()
print(f"获取执行状态: {p.poll()}")
3.2 执行结果:
获取返回对象: <subprocess.Popen object at 0x0028C4B0>
获取pid: 5260
获取返回数据: chinablue
获取执行状态: 0
3.3 分析小结:
1 ) subprocess.Popen()方法是一个异步方法,执行后会返回一个Popen对象
2 ) 获取子进程的标准输出(stdout)和标准错误(stderr)
方式1:通过p.stdout和p.stderr获取,如上例所示
方式2:通过p.communicate()获取,它返回一个元祖,元祖的第1个元素为stdout内容,元祖的第2个元素为stderr内容
p = subprocess.Popen("echo chinablue", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
print(f"获取返回数据: {p.communicate()[0]}")
print(f"获取返回错误: {p.communicate()[1]}")
3 ) 获取命令的执行状态:p.poll()
如果执行完subprocess.Popen()方法后,立即获取命令的执行状态, 则返回结果为None,因为此时子进程扔在运行中
如果我们需要等待子进程运行完毕后,再去获取命令的执行状态。那么我们可以使用p.wait()方法,这相当于将默认的异步操作改为同步操作
p = subprocess.Popen("echo chinablue", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
print(p.poll()) # 运行结果: None
p.wait()
print(p.poll()) # 运行结果: 0
四. 常见场景举例
场景1:在windows下,执行ipconfig命令并对结果进行过滤
# -*- coding:utf-8 -*-
# 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
# 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
import subprocess# 步骤1:将ipconfig命令的执行结果写入output.txt文件
with open("output.txt", "w") as f:subprocess.run("ipconfig", shell=True, stdout=f, universal_newlines=True, encoding="utf-8")
# 步骤2:将p1的输出内容作为p2的输入内容
p1 = subprocess.run("type output.txt", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
p2 = subprocess.run("findstr IPv4", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, input=p1.stdout)
print(p2.stdout)
场景2:在windows下,模拟并发执行命令
# -*- coding:utf-8 -*-
# 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
# 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
import time
import subprocess# 模拟一条耗时命令,此命令在windows下执行相当于sleep 2s
cmd = "ping -n 3 127.0.0.1 > nul"start_time = time.time()
p1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
p2 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
p1.wait()
p2.wait()
print(f"运行时间共计:{int(time.time() - start_time)}s")
# p1和p2命令执行各需耗时2s,通过并发执行后共计耗时也是2s
场景3:自动处理命令行交互
# -*- coding: utf-8 -*-
import subprocess# 这是一条对视频文件进行处理的命令(改变视频分辨率,同时将视频设置为倍速播放)
cmd = f'ffmpeg -i "dj_xiaomi.mp4" -s vga -filter:v "setpts=0.5*PTS" output.mp4'
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)# 命令在执行过程中,如果本地已经存在有output.mp4文件, 那么命令行处会出现提示符: File 'output.mp4' already exists. Overwrite? [y/N]
buff = ''
while True:output = p.stdout.read(1)if output:buff += outputelse:break# 出现提示符([y/N])后,程序可以自行处理此交互行为if buff.endswith("[y/N]"):p.communicate(input="y")break
另外python中的pexpect模块更擅长解决命令行的自动交互问题
python3中使用subprocess模块执行外部命令相关推荐
- python3使用subprocess_python3中使用subprocess模块执行外部命令
一. subprocess模块介绍 1. subprocess模块可以替代os模块下的os.system和os.popen等操作方法 2. subprocess模块在python2和python3上的 ...
- python的subprocess模块执行shell命令
subprocess模块可以允许我们执行shell命令 一般来说,使用run()方法就可以满足大部分情况 使用run执行shell命令 In [5]: subprocess.run('echo &qu ...
- python执行的命令_如何在Python中执行外部命令
Python子进程模块允许生成新进程,从Python脚本执行外部命令. 您可以使用这些教程来安装最新版本的Python. 此外,还有许多可用于Python IDE. 就像在Ubuntu系统上安装PyC ...
- python3 subprocess.check_output 执行shell命令 返回结果
Python3中的subprocess.check_output函数可以执行一条sh命令,并返回命令的输出内容,用法如下: output = subprocess.check_output([&quo ...
- vi执行Linux命令,如何从Vim中访问shell或运行外部命令
您可能已经知道,Vim是功能强大且功能强大的编辑器. 在Howtoing中,我们在Vim上编写了几个教程,涵盖了其基本用法 , 插件以及其他一些有用的功能. 但是鉴于Vim提供的功能,我们总是找到一些 ...
- java 执行外部命令 苹果_Java中执行外部命令
在项目中执行一个linux的shell脚本,于是需要在java环境下执行外部命令如系统命令.linux命令的需求,本人小小研究了一下,又上网查了一些资料先整理如下. java执行外部命令主要依赖两个类 ...
- 在awk中执行外部命令
在awk中执行外部命令 1.借助system/getline删除 awk '{cmd="rm "$0;system(cmd)}' filename awk '{cmd=" ...
- php在linux中执行外部命令
目录: 一.PHP中调用外部命令介绍 二.关于安全问题 三.关于超时问题 四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍 在PHP中调用外部命令,可以用,1>调用 ...
- python执行外部命令或URL
在Python/wxPython环境下,执行外部命令或者说在Python程序中启动另一个程序的方法一般有这么几个: 1.os.system(command) 2.wx.Execute(command, ...
最新文章
- hibernate和struts2实现分页功能
- IOS中Key-Value Coding (KVC)的使用详解
- 最感动的一首现代诗(转)(修正了一点翻译)
- 为什么要设置java环境变量_为什么要配置JDK环境变量?
- c#中out和ref的使用区别 [转]
- 【新星计划】Matlab绘制分岔图
- 服务器 Font family [‘sans-serif‘] not found.Falling back to DejaVu Sans.解决办法
- c++设计模式:访问者模式(visitor模式)
- python学习-条件语句
- java合并list_怎么把两个list合并
- java base64 显示不完整_如何解决CAD图纸显示不完整、图纸无效?一分钟教你,不允许错过...
- linux 安装rpm qt can't creat,CentOS 6.2部署Qt开发环境
- redis在Windows下以后台服务一键搭建集群(多机器)
- 原生JS操作DOM对象
- SAP UI5 应用开发教程之六十一 - 在 SAP UI5 应用里绘制甘特图 Gantt Chart 试读版
- VMware Fusion 虚拟网络配置
- ajax请求406,Ajax请求返回(406不可接受)
- linux枪战游戏,AstroMenace:好玩的太空射击游戏
- python之HTML-块级标签
- 在C/C++中整除符号和初始化数值应该注意细节