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 相关文章推荐
Django中更新多个对象数据与删除对象的方法
Jul 17 Python
Python按行读取文件的简单实现方法
Jun 22 Python
Python编程实现线性回归和批量梯度下降法代码实例
Jan 04 Python
对python cv2批量灰度图片并保存的实例讲解
Nov 09 Python
详解numpy的argmax的具体使用
May 27 Python
Django REST Framework序列化外键获取外键的值方法
Jul 26 Python
对Python 中矩阵或者数组相减的法则详解
Aug 26 Python
django实现后台显示媒体文件
Apr 07 Python
python实现四人制扑克牌游戏
Apr 22 Python
keras处理欠拟合和过拟合的实例讲解
May 25 Python
python爬虫构建代理ip池抓取数据库的示例代码
Sep 22 Python
详解Django关于StreamingHttpResponse与FileResponse文件下载的最优方法
Jan 07 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设计模式之工厂模式用法经典实例分析
2019/09/20 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
JS 文件传参及处理技巧分析
2010/05/13 Javascript
你需要知道的10个最佳javascript开发实践小结
2012/04/15 Javascript
javascript打印大全(打印页面设置/打印预览代码)
2013/03/29 Javascript
jQuery实现带分组数据的Table表头排序实例分析
2015/11/24 Javascript
浅谈javascript中的加减时间
2016/07/12 Javascript
JS弹出窗口的运用与技巧大全
2016/11/01 Javascript
详解Js模板引擎(TrimPath)
2016/11/22 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
详解react关于事件绑定this的四种方式
2018/03/09 Javascript
详解VueJs中的V-bind指令
2018/05/03 Javascript
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
微信小程序上线发布流程图文详解
2019/05/06 Javascript
解决vue打包后vendor.js文件过大问题
2019/07/03 Javascript
移动端吸顶fixbar的解决方案详解
2019/07/17 Javascript
vue结合el-upload实现腾讯云视频上传功能
2020/07/01 Javascript
关于vue 结合原生js 解决echarts resize问题
2020/07/26 Javascript
微信小程序实现可长按移动控件
2020/11/01 Javascript
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
使用Python编写一个模仿CPU工作的程序
2015/04/16 Python
python字符串编码识别模块chardet简单应用
2015/06/15 Python
Tensorflow 合并通道及加载子模型的方法
2018/07/26 Python
详解Python二维数组与三维数组切片的方法
2019/07/18 Python
python json 递归打印所有json子节点信息的例子
2020/02/27 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
2020/03/06 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
HTML5的文档结构和新增标签完全解析
2017/04/21 HTML / CSS
HTML5 实现一个访问本地文件的实例
2012/12/13 HTML / CSS
StubHub希腊:购买体育赛事、音乐会和剧院门票
2019/08/03 全球购物
存储过程的优点有哪些
2012/09/27 面试题
小学端午节活动方案
2014/03/13 职场文书
公司董事长岗位职责
2014/06/08 职场文书
品质标语大全
2014/06/21 职场文书
高中校园广播稿
2014/10/21 职场文书