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 ...
随机推荐
- 在线P图工具(基于minipaint开发)
在浏览github过程中,发现一个超级实用的仓库,viliulsle开发的minipaint,类似于photoshop的网页版.基于webpack开发的,打包非常简单,故自己搭建了一套. 在线预览 在 ...
- SD Host控制器微架构设计-02
SD_clk 测试模式下,选择hclk,将扫描链中的时钟保持一致 clk_en表示可以通过软硬件关闭时钟 sd_if模块 模块中设置一些寄存器,我们可以对寄存器进行读写或者对于寄存器中的某些域段进行读 ...
- 【ARM】重新定义低级库函数,以便能够直接使用 C 库中的高级库函数
Redefining low-level library functions to enable direct use of high-level library functions in the C ...
- [转帖]Archery
Archery SQL 审核查询平台 文档 | FAQ | Releases 功能清单 数据库 查询 审核 执行 备份 数据字典 慢日志 会话管理 账号管理 参数管理 数据归档 My ...
- [转帖]Oracle进程中的 LOCAL=NO 和 LOCAL=YES
https://www.cnblogs.com/wjoyxt/p/3780860.html 我们在服务器上用sqlplus 连接数据库,在查看进程,会多出一条记录: oracle 16007 1600 ...
- [转帖]Tiup 常用运维操作命令干货
https://zhuanlan.zhihu.com/p/356031031 **导读**> 作者:杨漆> 16年关系型数据库管理,从oracle 9i .10g.11g.12c到Mysq ...
- kafka的学习之二_kafka的压测与GUI管理
kafka的学习之二_kafka的压测与GUI管理 第一部分创建topic cd /root/kafka_2.13-3.5.0 bin/kafka-topics.sh --create --boots ...
- [转帖]xargs详解
https://www.cnblogs.com/xiaofeng666/p/10800939.html xargs与find经常结合来进行文件操作,平时删日志的时候只是习惯的去删除,比如 # find ...
- [转帖]iozone磁盘读写测试工具的使用以及命令详解、下载(网站最详细讲解步骤)
一.iozone简介 iozone是一款开源工具,用来测试文件系统的读写性能,也可以进行测试磁盘读写性能. 二.下载 方式一:网站下载http://www.iozone.org/ 方式二:个人网盘存放 ...
- [转帖]QPS、TPS、RT、并发数、吞吐量理解和性能优化深入思考
https://baijiahao.baidu.com/s?id=1675704570461446033&wfr=spider&for=pc 吞吐量 在了解qps.tps.rt.并发数 ...