Python中使用PIPE操作Linux管道


Posted in Python onFebruary 04, 2015

Linux中进程的通信方式有信号,管道,共享内存,消息队列socket等。其中管道是*nix系统进程间通信的最古老形式,所有*nix都提供这种通信方式。管道是一种半双工的通信机制,也就是说,它只能一端用来读,另外一端用来写;另外,管道只能用来在具有公共祖先的两个进程之间通信。管道通信遵循先进先出的原理,并且数据只能被读取一次,当此段数据被读取后,马上会从数据中消失,这一点很重要。

Linux上,创建管道使用pipe函数,当它执行后,会产生两个文件描述符,分别为读端和写端。单个进程中的管道几乎没有任何作用,通常会先调用pipe,然后调用fork,从而创建从父进程到子进程的IPC通道。

Python中使用PIPE操作Linux管道

Linux中,我们经常会使用到管道,例如用cat命令查看一个大文件时,一页不能全部显示,我们可以通过cat xxx | more来分页显示,又比如搜索文件里的内容可以用 cat xxx | grep search来进行,这里我们都用到了管道。接下来我会用python编写一段自动分页显示的程序,而不用手动来使用管道。

#!/usr/bin/env python
import os,sys
if not sys.argv[1:]:
  print "No filename input"
  sys.exit(1)
try:
    fp = open(sys.argv[1],"r")
except IOError,msg:
  sys.exit(msg)
pi=os.pipe()
pid=os.fork()
if pid:
  #parent
  os.close(pi[0]) #close read pipe
  #write to pipe
  line=fp.readline()
  while line:
    os.write(pi[1],line)
    line=fp.readline()
  #close write pipe
  os.close(pi[1])
  #wait for chile
  os.waitpid(pid,0)
else:
  os.close(pi[1]) #close write pipe
  #put pipe read to stdin
  os.dup2(pi[0],sys.stdin.fileno())
  os.close(pi[0])
  os.execl("/bin/more","more")

把这段代码存为scat.py,增加执行权限之后,运行 scat.py 文件名,系统就会自动读取文件的内容并分页,与使用 cat 文件名 | more 的效果是一模一样的。在上面的代码中,用到了前几篇博客中说的fork,dup2和exec系列函数。

首先是程序创建了一个管道,系统fork之后,父进程关闭其读端,子进程关闭其写端,接下来父进程读取传递过来的文件名,并把内容通过管道的写入端口写入管道里,然后关闭写入端口,并等待子进程的结束。子进程在关闭写入端口后,把读取端口重定向到进程的标准输入,子进程就能自动接收到管道传递过来的数据,最后用execl函数调用系统的more程序用来处理传递过来的数据,这样,就轻松实现的分页的效果。

pipe是半双工的通信机制,如果进程间要使用全双工的通信,可以创建两条管道来达到全双工的效果。另外,pipe匿名管道只能用来在拥有同一个父进程的进程间通信,*nix提供另外一个fifo(命名管道)可以让任意的进程之间实现通信,会在接下来的博客中来讲。

Python 相关文章推荐
python中二维阵列的变换实例
Oct 09 Python
用Python制作检测Linux运行信息的工具的教程
Apr 01 Python
基于python实现微信模板消息
Dec 21 Python
Python实现ssh批量登录并执行命令
Oct 25 Python
Python  pip安装lxml出错的问题解决办法
Feb 10 Python
浅谈django开发者模式中的autoreload是如何实现的
Aug 18 Python
python 反编译exe文件为py文件的实例代码
Jun 27 Python
python找出因数与质因数的方法
Jul 25 Python
Python大数据之使用lxml库解析html网页文件示例
Nov 16 Python
Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
Dec 09 Python
Python selenium爬虫实现定时任务过程解析
Jun 08 Python
如何表示python中的相对路径
Jul 08 Python
Python实现在Linux系统下更改当前进程运行用户
Feb 04 #Python
使用Python编写Linux系统守护进程实例
Feb 03 #Python
Python中使用select模块实现非阻塞的IO
Feb 03 #Python
Python异常学习笔记
Feb 03 #Python
Python中的迭代器漫谈
Feb 03 #Python
Python描述器descriptor详解
Feb 03 #Python
理解Python中的With语句
Feb 02 #Python
You might like
Zerg建筑一览
2020/03/14 星际争霸
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
php define的第二个参数使用方法
2013/11/04 PHP
解决cPanel无法安装php5.2.17
2014/06/22 PHP
php设计模式之委托模式
2016/02/13 PHP
javascript 兼容鼠标滚轮事件
2009/04/07 Javascript
20款超赞的jQuery插件 Web开发人员必备
2011/02/26 Javascript
JavaScript通过RegExp实现客户端验证处理程序
2013/05/07 Javascript
鼠标移到div,浮层显示明细,弹出层与div的上边距左边距重合(示例代码)
2013/12/14 Javascript
浅谈Jquery核心函数
2015/06/18 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
原生JS:Date对象全面解析
2016/09/06 Javascript
如何编写jquery插件
2017/03/29 jQuery
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
2017/12/11 jQuery
解决webpack无法通过IP地址访问localhost的问题
2018/02/22 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
解决axios发送post请求返回400状态码的问题
2018/08/11 Javascript
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
vue中的使用token的方法示例
2020/03/10 Javascript
javascript设计模式 ? 工厂模式原理与应用实例分析
2020/04/09 Javascript
[45:50]完美世界DOTA2联赛PWL S3 CPG vs Forest 第二场 12.16
2020/12/17 DOTA
Python常用的爬虫技巧总结
2016/03/28 Python
python网络爬虫之如何伪装逃过反爬虫程序的方法
2017/11/23 Python
在Python 不同级目录之间模块的调用方法
2019/01/19 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
Python程序慢的重要原因
2020/09/04 Python
将世界上最美丽的摄影作品转化为艺术作品:Photos.com
2017/11/28 全球购物
GAZMAN官网:澳大利亚领先的男装品牌
2019/12/19 全球购物
学习新党章思想汇报
2014/01/09 职场文书
社会调查研究计划书
2014/05/01 职场文书
求职自我推荐信
2014/06/25 职场文书
2016学雷锋优秀志愿者事迹材料
2016/02/25 职场文书
python 进阶学习之python装饰器小结
2021/09/04 Python
python实现商品进销存管理系统
2022/05/30 Python