Python subProcess库以及Popen类的使用
subprocess库是一个十分强大且常用的库,它可以用来调用第三方工具(例如:exe、另一个python文件、命令行工具)。
1.常用函数
call() :执行由参数提供的命令,把数组作为参数运行命令。
retcode = subprocess.call(["ls", "-l"])
【注意1】 在Linux系统中上述代码运行没有问题,但是在windows中上述代码运行会报错:FileNotFoundError: [WinError 2] 系统找不到指定的文件。这是由于call函数的shell参数默认为False状态,这个状态windows下并不支持,需要修改shell为True状态:
retcode = subprocess.call("ls -l",shell=True)
【注意2】 call函数建议在Linux系统中使用,在Windows系统中有诸多限制。在Linux系统中,call函数会直接打印出参数运行后的结果,而赋值的是返回结果,而非运行结果。例如下面的运行结果,直接打印出目录,但r的值为0。
【注意3】 在Windows系统下使用call函数要注意命令的区别,例如:复制应该是“copy”而非“cp”。
错误代码:
subprocess.call(['cp', train_blur[index], os.path.join(args.output_path, 'train\\blur\\%s'%('_'.join(train_blur[index].split('\\')[-3:])))], shell=True)
正确代码:
subprocess.call(['copy', train_blur[index], os.path.join(args.output_path, 'train\\blur\\%s'%('_'.join(train_blur[index].split('\\')[-3:])))], shell=True)
【注意4】 在使用call函数的时候尽量不要使用shell的True参数,会造成安全上的问题。
※运行代码:
retcode = subprocess.call(["ls", "-l"])
check_call():和上面的call()作用相同,唯一的不同点在于对于返回值的处理上。
当call()函数和check_call()函数的返回值都为1的时候:
check_call()函数的返回值为1的时候会报错。并且check_call()函数会把运行结果赋值给变量,而call()函数会把返回值复制给变量。
check_output():和上面的两个函数作用相同,唯一的不同点是,这个函数可以获得返回的结果。
2. Popen模块
Popen():相较于上面的三个函数,popen()更加精细化,上面的三个函数都是父进程会等待子进程结束,但是popen()函数只有在使用 wait() 时才会等待。所以,上面的三个函数相当于,popen+wait的组合。
child = subprocess.Popen(['ping','-c','4','127.0.0.1'])
child.wait(4)
#或
child = subprocess.Popen('ping -c4 127.0.0.1',shell=True)
child.wait(4)
wait()还可以设置超时时间,超过时间父进程将就不在等待了。
结果如图:
Popen还有三个参数,分别为:stdin、stdout、stderr。
例如:
p2 = subprocess.Popen(["grep","0:0"],stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout是标准输出重定向;
stdin:我们可以看到,结果被储存进了subprocess.PIPE里,实际上,subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),我们也可以利用这个特性,将stdout和stdin一起使用进行连续的输入输出:
c1 = subprocess.Popen(["uname","-a"], stdout=subprocess.PIPE)
c2 = subprocess.Popen(["wc"],stdin=child1.stdout,stdout=subprocess.PIPE)
out = c1.communicate()
print(out)
out = c2.communicate()
print(out)
subprocess.PIPE实际上为文本流提供一个缓存区。c1的stdout将文本输出到缓存区,随后c2的stdin从该PIPE中将文本读取走。c2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
stderr:不常用,返回错误信息,我们可一对其进行标准输出,例如:
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
【注意1】 communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。
communicate() 返回一个元组 (stdout_data, stderr_data) 。如果流以文本模式打开,则数据将是字符串;否则,字节。
请注意,如果要将数据发送到进程的标准输入,则需要使用 stdin=PIPE 创建 Popen 对象。同样,要在结果元组中获得除 None 以外的任何内容,您还需要提供 stdout=PIPE 和/ 或 stderr=PIPE。
如果进程在 timeout 秒后没有终止,则会引发 TimeoutExpired 异常。捕获此异常并重试通信不会丢失任何输出。
如果超时到期,子进程不会被杀死,因此为了正确清理well-behaved应用程序应该杀死子进程并完成通信:
【注意2】 pipe的有大小限制,Linux默认的pipe size是64KB。当大于64kb时,如果使用 Popen.wait() 方式等待程序结束获取返回值,会导致死锁,程序卡在 wait() 调用上。communicate将数据不是放在pipe中,而是放在内存中
所以,推荐使用communicate方式获得返回结果
【注意3】 输出输入小技巧:当参数传入不进去的时候,例如ip地址,可以将参数拼接在一起传入,例如(注意“ip”前面的加号+):
p=subprocess.Popen("ping -c 4 " + ip, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
3. 子进程常用方法
child.pid:返回子进程的pid
child.poll() :检查子进程状态
child.kill() :终止子进程
child.send_signal() :向子进程发送信号
child.terminate() :终止子进程
Python subProcess库以及Popen类的使用的更多相关文章
- Python - 标准库部分函数、类的大致实现(持续更新)
all() def all(iterable): for element in iterbale: if not element: return False return True any() def ...
- Python标准库06 子进程 (subprocess包)
这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说, ...
- Python标准库---子进程 (subprocess包)
这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说, ...
- Python标准库之subprocess模块
运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python中,我们通过标准库中的subprocess ...
- Python多进程库multiprocessing中进程池Pool类的使用[转]
from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...
- Python subprocess.Popen communicate() 和wait()使用上的区别
之所以会纠结到这个问题上是因为发现在调用Popen的wait方法之后程序一直没有返回.google发现wait是有可能产生死锁的.为了把这个问题彻底弄清楚,搜索一些资料过来看看: 原文链接:http: ...
- Python标准库——collections模块的Counter类
1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类 ...
- Python subprocess.Popen中communicate()和wait()区别
刚开始我是使用的wait(),但是当adb命令返回太多时,程序就会卡死,查询得知原因后,才使用了communicate(),communicate()返回一个元组:(stdoutdata, stder ...
- python subprocess popen 静默模式(不弹出console控制台)
python subprocess popen 静默模式(不弹出console控制台) import subprocess,sys IS_WIN32 = 'win32' in str(sys.plat ...
- python - 标准库:subprocess模块
subprocess的目的就是启动一个新的进程并且与之通信. subprocess模块中只定义了一个类: Popen. subprocess.Popen(args, bufsize=0, execut ...
随机推荐
- WebApi的输出结果重写 OnActionExecuted
public override void OnActionExecuted(ActionExecutedContext context) { if (context.Exception != null ...
- SpringBoot03:首页国际化
页面国际化 有的时候,我们的网站会去涉及中英文甚至多语言的切换,这时候我们就需要学习国际化! 1.配置文件编写 首先在resources资源文件下新建一个i18n目录,存放国际化配置文件 新建一个lo ...
- 【面试题精讲】说一说springboot加载配置文件优先级
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 文章更新计划 系列文章地址 Spring Boot 加载配置文 ...
- [转帖]手摸手搭建简单的jmeter+influxdb+grafana性能监控平台
我安装的机器是阿里云的centos8机器,其他的系统暂未验证 1.安装influxdb influxdb 下载地址https://portal.influxdata.com/downloads/,也可 ...
- [转帖]【Redis】Redis中使用Lua脚本
Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua具体语法参考:https://www.runoob. ...
- [转帖]NVMe 与 AHCI
https://www.cnblogs.com/zengkefu/p/5634345.html http://elf8848.iteye.com/blog/1731274 AHCI: NCQ技术,60 ...
- [转帖]Linux内核映像vmlinux、Image、zImage、uImage区别
https://zhuanlan.zhihu.com/p/466226177 本文介绍几种常用的Linux内核映像的区别. 一.vmlinux vmlinux:Linux内核编译出来的原始的内核文件, ...
- [转帖]人脸特征计算速度优化-SIMD技术Neon介绍
人脸特征计算速度优化-SIMD技术Neon介绍 JasonZhu 游走于秃头和研究的边缘 关注 15 人赞同了该文章 目录 收起 1. baseline计算 2. simd和数据重排加速 数 ...
- STM32CubeMX教程25 PWR 电源管理 - 睡眠、停止和待机模式
1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...
- 简述if if和if else的关系与区别
简述if if和if else的关系与区别 当满足条件1,条件2都会执行的哈. 双if是每一个if都会进行判断,依次对if进行判断,互相之间不会影响; if(条件1){ 要执行的语句; } if(条件 ...