使用subprocess.Poen注意事项
学习使用python已经有四个月了,subprocess这个执行linux中shell命令的函数已经用过无数次了,踩到的坑也有几个,写出来分享一下,欢迎大家拍砖头。
1.shell命令中若有管道,一定要多次调用Poen,p1的输出当作p2的输入。
例如:shell命令
hdfs dfs -cat test.log.lzo | lzop -d | head -n 2
此命令可以查看hdfs上面一个lzo文件中的前两行,开始没有看subprocess的手册,直接代码就写成:
shell_comm="hdfs dfs -cat test.log.lzo | lzop -d | head -n 2"
outPipe=subprocess.Popen(shell_comm,shell=True,stdout=subprocess.PIPE)
结果输出那是一堆乱码,纠结了半天,一直以为是编码不统一的问题,找了N久,郁闷良久,最后老大跟我说,subprocess不是这样用的,管道必须使用多个popen,代码改成:
comm1="hdfs dfs -cat test.log.lzo"
comm2="lzop -d"
comm3="head -n 2"
p1=subprocess.Popen(comm1,shell=True,stdout=subprocess.PIPE)
p2=subprocess.Popen(comm2,shell=True,stdoin=p1.stdout,stdout=subprocess.PIPE)
p3=subprocess.Popen(comm3,shell=True,stdoin=p2.stdout,stdout=subprocess.PIPE)
最后p3的输出就是你想要的结果了
2.python2.7多个管道连接输出会出现Broken pipe提示。
像上面代码中多个管道连续输出,最后p3却只取前2行,comm1|2在一直不停的执行,comm3却终止了,此时就会出现Broken pipe提示,这是python的一个bug,具体原因和解决办法可见http://bugs.python.org/issue1652 https://code.google.com/p/python-subprocess32/
3.subprocess一定要收集子进程状态
这就牵扯到我写代码过程中跳的一个坑,看网上写的使用subprocess的例子,都是直接执行命令,然后读取PIPE内容,我也照做,根本没有想到收集什么进程状态这回事。有一天,老大把我叫过去,看着我说:“我发现一个问题,为什么每次你写的这个程序运行起来,服务器内存使用量一下子就上升了2、3十G?”
经过各种traceback和lsof查看进程状态,发现罪魁祸首居然是subprocess,最重要的是我调用了subprocess.Popen之后没有收集子进程状态。我的整个程序运行了5、6分钟,打开了hdfs上的上百个文件,而且都是取开头两行,开启了N个子进程,都没有收集,那么这些子进程的数据全部都算在了程序主进程中,一直占用服务器内存,并且越堆积越多。最后加上状态收集语句之后问题解决。
4.subprocess.wait()与subprocess.communicate()使用问题
subprocess就是开启一个子进程,自己去执行命令,这个子进程的状态肯定得收集,这时候就需要调用wait或者communicate了,手册上面也注明了这两个方法的特点:在数据超过PIPE的缓存时,wait会阻塞进程;communicate会把所有的数据都读取到内存中。
wait:
Warning
This will deadlock if the child process generates enough output to a stdout or stderr pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.
communicate:
Note
The data read is buffered in memory, so do not use this method if the data size is large or unlimited
那么现在就有一个问题了,当我shell命令执行的结果很大时,我是该用wait还是communicate?用wait直接就阻塞了,肯定不行,用communicate也不行,如果很大的文件,数据都保存在内存,主机直接就卡死了。
解决办法:数据一行一行读取,读取完之后wait,这样既保证了不会阻塞(PIPE中数据有进有出,最后空了才wait),又保证了不会占用大量主机内存(在内存中的数据只有一行line)。
p1=subprocess.Popen(comm1,shell=True,stdout=subprocess.PIPE)
for line in p1.stdout:
pass
p1.wait()
使用subprocess.Poen注意事项的更多相关文章
- python的subprocess的简单使用和注意事项
subprocess是python在2.4引入的模块, 主要用来替代下面几个模块和方法: os.systemos.spawn*os.popen*popen2.*commands.* 可以参考PEP32 ...
- python的subprocess:子程序调用(调用执行其他命令);获取子程序脚本当前路径问题
python当前进程可以调用子进程,子进程可以执行其他命令,如shell,python,java,c... 而调用子进程方法有 os模块 参见:http://blog.csdn.net/longshe ...
- jQuery UI resizable使用注意事项、实时等比例拉伸及你不知道的技巧
这篇文章总结的是我在使用resizable插件的过程中,遇到的问题及变通应用的奇思妙想. 一.resizable使用注意事项 以下是我在jsfiddle上写的测试demo:http://jsfiddl ...
- Windows Server 2012 NIC Teaming介绍及注意事项
Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- app开发外包注意事项,2017最新资讯
我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...
- favicon.ioc使用以及注意事项
1.效果 2.使用引入方法 2.1 注意事项:(把图标命名为favicon.ico,并且放在根目录下,同时使用Link标签,多重保险) 浏览器默认使用根目录下的favicon.ico 图标(如果你并没 ...
- ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- 【原】Masonry+UIScrollView的使用注意事项
[原]Masonry+UIScrollView的使用注意事项 本文转载请注明出处 —— polobymulberry-博客园 1.问题描述 我想实现的使用在一个UIScrollView依次添加三个UI ...
随机推荐
- Eclipse下高亮显示Freemarker文件
让eclipse高亮显示freemarker文件有两种方式,一种是安装JBoss的插件,一种是用JSP编辑器打开freemarker的文件.我使用第二种方式来完成. 打开eclipse,点击windo ...
- 360Vedio To NFOV Vedio
Deep 360 Pilot Learning a Deep Agent for Piloting through 360° Sports Videos 源码.数据集和视频演示 ego-centric ...
- 交换机、linux光衰查询
RX收光,TX发光 一.交换机 命令: display interface transceiver brief 结果: ...... HW6851 10GE1/0/15 transceiver dia ...
- ini_set的权限大于error_reporting
在用php做网站开发的时候 , 为防止用户看到错误信息,而出现的不友好界面.故一般性会在php.ini里设置:display_errors = Off;不过在开发的时候,我们有时候需要打开错误信息.这 ...
- java 加载过程
1.main方法进入方法区 2.main方法进栈 3.调用xxx类加载到jvm中 类属性进入数据共享区,方法进入到方法区
- Milk Patterns POJ - 3261(后缀数组+二分)
题意: 求可重叠的最长重复子串,但有一个限制条件..要至少重复k次 解析: 二分枚举k,对于连续的height 如果height[i] >= k 说明它们至少有k个元素是重复的,所以判断一下就好 ...
- hdu1542 Atlantis (线段树+矩阵面积并+离散化)
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- expect ssh 自动登录 example
#!/usr/bin/expect -f set ip [lindex $argv ] set port [lindex $argv ] set username [lindex $argv ] se ...
- Spring boot项目集成Sharding Jdbc
环境 jdk:1.8 framework: spring boot, sharding jdbc database: MySQL 搭建步骤 在pom 中加入sharding 依赖 <depend ...
- BZOJ1443 [JSOI2009]游戏Game 【博弈论 + 二分图匹配】
题目链接 BZOJ1443 题解 既然是网格图,便可以二分染色 二分染色后发现,游戏路径是黑白交错的 让人想到匹配时的增广路 后手要赢[指移动的后手],必须在一个与起点同色的地方终止 容易想到完全匹配 ...