Python subprocess 子进程管理(一)

最近在改进自动化框架的启动模块,从而能够把robot的所有输出写入到日志文件中以便查看,也为下一步研究selenium grid打下基础。在这个过程中看了不少有关python中通过subprocess运行外部命令的资料,所以就顺便写下来以便日后温习。一下所有的内容都基于Windows中python2.7的环境,Unix和python3中会稍有不同。

在搜索通过python 运行外部命令的文章中总能看到诸如os.system, os.popen 和 subprocess.Popen区别的文章。这也着实让我迷惑了一阵,到底用哪一个才是比较好的方案。看了官方的文档之后才豁然开朗。The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions。答案很明显,subprocess模块就是用来替换之前的那些旧模块的。所以我们直接学习subprocess就可以了。

在subprocess模块中提供了3个方法和一个类来实现运行管理子进程,官方建议普通的运用中我们可以直接调用提供的函数来快速完成子进程的运行,并获取运行结果。只有在高级应用是才考虑使用Popen类。第一部分先介绍这三个快捷函数。

subprocess.call(args*stdin=Nonestdout=Nonestderr=Noneshell=False)

以下是常用的参数介绍,完全的参数项跟Popen一样,因为在call的时候并不推荐使用所以就略去了。执行成功会返回returncode属性。

args: 可以是一个string,数组或者列表。用来存放需要执行的命令和参数,例如‘echo hello’或者('echo', 'hello')

stdin, stdout,stderr分别就是标准输出,标准输入,标准错误输出。如果去默认值则继承自父进程的相关设定,也可以指向PIPE或一个文件对象。

shell:布尔值,是否调用一个shell来执行。当为true时会调用系统默认的shell环境来执行命令。对于windows的环境来说,只有当需要运行cmd内置命令的时候才需要设为true。

下面举两个shell的例子


这里运行了cmd的echo来打印hello。如果不把shell设置为True则会抛出WindowsError,就像在Windows里直接执行一个没有后缀的文件,Windows便不知道如何执行它。shell为True时会调用cmd来执行echo命令,自然就没有问题了。运行成功的话,call返回了returncode 0.

下面再看一个例子,这里直接运行cmd.exe。运行成功了,显示了cmd的命令提示符。因为cmd.exe在Windows里是一个可执行文件,所以不需要再调用cmd去执行他。


再举一个stdin重定向的例子,先将echo hello存在d:/test.txt. 通过将stdin指向从文件读取命令。


subprocess.check_call(args*stdin=Nonestdout=Nonestderr=Noneshell=False)

所有的参数与call一模一样,就不在累述了。功能上与call大部分一样,只是当返回的return code不为0时会抛出CallProcessError,而call不会。如下:


subprocess.check_output(args*stdin=Nonestderr=Noneshell=Falseuniversal_newlines=False)

除了universal_newlines,其他的参数与call一致。universal_newlines为Ture时表示在stdout,stderr指向PIPE或file object时会使用universal_newlines的方式写入。什么是universal_newlines呢?请移步这篇blog,很好的介绍了这种方式https://blog.tankywoo.com/2015/01/11/python-universal-newlines.html

从功能上来说它与check_output很相似,不同的是会将子进程的output作为一个byte string返回,而不是打印到标准输出。从下面这个例子可以看出区别。运行check_output没有打印出dir命令的结果,而是返回给了dir变量。运行check_call则是直接打印出了dir命令的结果,返回的只是return code的值


注意:

官方特别强调在运用这三个函数时,不要使用stderr=PIPE如下. 主要的原因是如果输出大量数据超出缓存造成管道堵塞的话,会导致死锁函数会hang在那里。在这个情况下使用Popen的communicate()方法,会将stderr的内容加载到内存中。

Note

 

Do not use stderr=PIPE with this function as that can deadlock based on the child process error volume. Use Popen with the communicate() method when you need a stderr pipe.



今天就先介绍这三个快捷函数,相信大部分的使用场景这三个函数就能够搞定了。Popen类在下一篇介绍

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值