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 基础学习第二弹 类属性和实例属性
Aug 27 Python
跟老齐学Python之模块的加载
Oct 24 Python
11个并不被常用但对开发非常有帮助的Python库
Mar 31 Python
python生成器generator用法实例分析
Jun 04 Python
python好玩的项目—色情图片识别代码分享
Nov 07 Python
python如何为被装饰的函数保留元数据
Mar 21 Python
python xpath获取页面注释的方法
Jan 14 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
Jun 18 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
Feb 04 Python
django 数据库 get_or_create函数返回值是tuple的问题
May 15 Python
如何利用Python动态模拟太阳系运转
Sep 04 Python
Python Pandas数据分析工具用法实例
Nov 05 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
php异步多线程swoole用法实例
2014/11/14 PHP
主流PHP框架的优缺点对比分析
2014/12/25 PHP
php判断表是否存在的方法
2015/06/18 PHP
PHP面向对象详解(三)
2015/12/07 PHP
php提交过来的数据生成为txt文件
2016/04/28 PHP
php利用嵌套数组拼接与解析json的方法
2017/02/07 PHP
php利用fsockopen GET/POST提交表单及上传文件
2017/05/22 PHP
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
2010/05/15 Javascript
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
jQuery实现按键盘方向键翻页特效
2015/03/18 Javascript
jQuery动态效果显示人物结构关系图的方法
2015/05/07 Javascript
javascript处理a标签超链接默认事件的方法
2015/06/29 Javascript
Function.prototype.apply()与Function.prototype.call()小结
2016/04/27 Javascript
轻松掌握JavaScript中介者模式
2016/08/26 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
JavaScript计算出两个数的差值
2020/03/19 Javascript
jQuery实现简单评论功能
2020/08/19 jQuery
python socket多线程通讯实例分析(聊天室)
2016/04/06 Python
Win10下Python环境搭建与配置教程
2016/11/18 Python
Python编程实现双链表,栈,队列及二叉树的方法示例
2017/11/01 Python
Python机器学习算法之k均值聚类(k-means)
2018/02/23 Python
python实现滑雪者小游戏
2020/02/22 Python
BeautifulSoup获取指定class样式的div的实现
2020/12/07 Python
利用纯CSS3实现文字向右循环闪过效果实例(可用于移动端)
2017/06/15 HTML / CSS
Carolina Lemke Berlin澳大利亚官网:时尚太阳镜品牌
2019/09/17 全球购物
Vita Fede官网:在意大利手工制作,在纽约市设计
2019/10/25 全球购物
解释一下钝化(Swap out)
2016/12/26 面试题
大学毕业后的十年规划
2014/01/07 职场文书
公司保密承诺书
2014/03/27 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python
React如何创建组件
2021/06/27 Javascript