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 ...
随机推荐
- 【FreeRTOS】任务调度
启动调度器接口,主要是创建空闲任务和定时器任务以及执行特定架构的启动调度器接口 // FreeRTOS\Source\tasks.c void vTaskStartScheduler( void ) ...
- [转帖]一次fork引发的惨案!
https://www.cnblogs.com/xuanyuan/p/15502289.html "你还有什么要说的吗?没有的话我就要动手了",kill程序最后问道. 这一次,我没 ...
- [转帖]nacos开启强鉴权
注意 Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险. Nacos提供简单的鉴权实现,为防止业务错用的弱鉴权体系,不是防止恶意攻击的强鉴权体系. 如果 ...
- 不想做架构师的Gopher不是好程序员
最近我们在组队学习<手把手带你写一个web框架>,强制PUSH,坚持每天学习打卡,不完成惩罚发红包的那种. 你别说,效果还真挺好. 昨天学到了架构部分,很受启发,光学不写假把式.(还是得坚 ...
- IConfigurationSectionHandler 接口的用法
今天终于花了点时间了解一下IConfigurationSectionHandler 接口的用法 ,引以入门.首先建立一 RobsunConfigSectionHandler 专案,代码如下 : nam ...
- P1962 斐波那契数列(矩阵快速幂)
#include<bits/stdc++.h> #define int long long using namespace std; int n,a[3],m=1e9+7,c[3][3], ...
- Windows 堆管理机制 [3] Windows XP SP2 – Windows 2003 版本
3. Windows XP SP2 – Windows 2003 3.1 环境准备 环境 环境准备 虚拟机 32位Windows XP SP2 \32位Windows XP SP3 调试器 OllyD ...
- 从零开始匹配vim(0)——vimscript 简介
通过之前一系列的文章,相信各位小伙伴应该已经对vim产生了浓厚的兴趣,可能不少小伙伴通过慢慢的使用变的跟我一样,离开vim就不会写代码了.如果你希望继续长时间使用vim,甚至将vim作为主要的代码编辑 ...
- 【Spring】Bean装配类注解
默认注入类型 多个同类型Bean 注入失败 依赖 使用目标(@Target) @AutoWired 通过type 默认首先安装属性名称进行注入 结合@Qualifier注解(value属性)设置注入的 ...
- 通过Demo学WPF—数据绑定(一)✨
前言 想学习WPF,但是看视频教程觉得太耗时间,直接看文档又觉得似懂非懂,因此想通过看Demo代码+文档的方式进行学习. 准备 微软官方其实提供了WPF的一些Demo,地址为:microsoft/WP ...