一. subprocess模块介绍

1. subprocess模块可以替代os模块下的os.system和os.popen等操作方法

2. subprocess模块在python2和python3上的使用上有一定的区别,本文主要介绍的是在python3.6上的使用

3. subprocess模块的作用是执行外部命令(支持同步执行和异步执行),可以返回执行状态码,也可以返回执行内容

4. subprocess模块的方法有很多,最核心的方法为subprocess.Popen方法,python3中如果只需要同步执行,优先使用subprocess.run方法

二. subprocess.run()方法的介绍

2.1 执行代码:在windows下执行一条cmd命令

#-*- coding:utf-8 -*-#Author:chinablue

importsubprocess#在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文件中

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

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 -*-#Author:chinablue

importsubprocess#在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 执行结果:

获取返回对象: 获取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 -*-#Author:chinablue

importsubprocess#步骤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 -*-#Author:chinablue

importtimeimportsubprocess#模拟一条耗时命令,此命令在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 -*-#@Author : chinablue

importsubprocess#这是一条对视频文件进行处理的命令(改变视频分辨率,同时将视频设置为倍速播放)

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 = ''

whileTrue:

output= p.stdout.read(1)ifoutput:

buff+=outputelse:break

#出现提示符([y/N])后,程序可以自行处理此交互行为

if buff.endswith("[y/N]"):

p.communicate(input="y")break

另外python中的pexpect模块更擅长解决命令行的自动交互问题

python3使用subprocess_python3中使用subprocess模块执行外部命令相关推荐

  1. python3中使用subprocess模块执行外部命令

    一. subprocess模块介绍 subprocess模块可以替代os模块下的os.system和os.popen等操作方法 subprocess模块在python2和python3上的使用上有一定 ...

  2. python的subprocess模块执行shell命令

    subprocess模块可以允许我们执行shell命令 一般来说,使用run()方法就可以满足大部分情况 使用run执行shell命令 In [5]: subprocess.run('echo &qu ...

  3. python执行的命令_如何在Python中执行外部命令

    Python子进程模块允许生成新进程,从Python脚本执行外部命令. 您可以使用这些教程来安装最新版本的Python. 此外,还有许多可用于Python IDE. 就像在Ubuntu系统上安装PyC ...

  4. vi执行Linux命令,如何从Vim中访问shell或运行外部命令

    您可能已经知道,Vim是功能强大且功能强大的编辑器. 在Howtoing中,我们在Vim上编写了几个教程,涵盖了其基本用法 , 插件以及其他一些有用的功能. 但是鉴于Vim提供的功能,我们总是找到一些 ...

  5. java 执行外部命令 苹果_Java中执行外部命令

    在项目中执行一个linux的shell脚本,于是需要在java环境下执行外部命令如系统命令.linux命令的需求,本人小小研究了一下,又上网查了一些资料先整理如下. java执行外部命令主要依赖两个类 ...

  6. 在awk中执行外部命令

    在awk中执行外部命令 1.借助system/getline删除 awk '{cmd="rm "$0;system(cmd)}' filename awk '{cmd=" ...

  7. php在linux中执行外部命令

    目录: 一.PHP中调用外部命令介绍 二.关于安全问题 三.关于超时问题 四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍 在PHP中调用外部命令,可以用,1>调用 ...

  8. python执行外部命令或URL

    在Python/wxPython环境下,执行外部命令或者说在Python程序中启动另一个程序的方法一般有这么几个: 1.os.system(command) 2.wx.Execute(command, ...

  9. Go 学习笔记(43)— Go 标准库之 os/exec(执行外部命令、非阻塞等待、阻塞等待、命令输出)

    1. 概述 golang 下的 os/exec 包执行外部命令包执行外部命令.它包装了 os.StartProcess 函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整. 与 ...

最新文章

  1. 开启2020高效办公,从团队知识管理开始
  2. 分享:Svg文件转换为图片(调用 Inkscape 命令行)
  3. java string 属性_String类型的属性和方法
  4. linux 安装java10
  5. boost::gil::view_type用法的测试程序
  6. /hgfs下无共享文件夹?/mnt下没有hgfs文件夹?vmhgfs-fuse:找不到命令?
  7. linux进程map,LInux环境运行mapReduce程序
  8. MySQL基础篇(07):用户和权限管理,日志体系简介
  9. 【更新汇总】FastReport系列更新|附下载
  10. 图像局部特征(十七)--DenseFeature
  11. 【转】IT从业人员必看的10个论坛
  12. 【169天】黑马程序员27天视频学习笔记【Day08-上】
  13. 解决WIN10下QTTabBar无法置于顶部
  14. 怎么查看服务器的详细信息,服务器查看详细信息
  15. linux格式化只读u盘,linux下FAT32格式u盘只读的问题及解决方法
  16. 范蠡传(司马迁-史记)
  17. 现货黄金有什么需要注意的?
  18. 互联网晚报| 8月18日|未婚已育女性办理生育津贴不需要结婚证;拼多多将上线跨境电商平台;小米汽车将采用宁德时代麒麟和比亚迪刀片...
  19. Shell攻关之运算符
  20. 销售宝:用财务软件做账要注意什么?

热门文章

  1. Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介
  2. 蓝松SDK - 卡点视频制作介绍
  3. 杭电ACM 动态规划 1 数塔
  4. 2022 华为 Java 高级面试题及答案
  5. hustoj 相关问题
  6. android 手势密码功能sdk,利用ActivityLifecycleCallBack监控app前后台状态切换,实现手势密码即九宫格解锁...
  7. think-cell高阶教程(3)——图表颜色使用excel数据的填充颜色
  8. 矩阵分析:特征值分解
  9. C语言实现扫雷游戏(超详细讲解+全部源码)
  10. 【何凯明】非局部连接网络 Non-local Neural Network