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 使用logging打印日志的实例
Apr 28 Python
Python 数值区间处理_对interval 库的快速入门详解
Nov 16 Python
对python内置map和six.moves.map的区别详解
Dec 19 Python
Flask框架钩子函数功能与用法分析
Aug 02 Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 Python
使用Python给头像戴上圣诞帽的图像操作过程解析
Sep 20 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
Jul 09 Python
一些关于python 装饰器的个人理解
Aug 31 Python
如何使用Python调整图像大小
Sep 26 Python
matplotlib实现数据实时刷新的示例代码
Jan 05 Python
python基础学习之递归函数知识总结
May 26 Python
如何使用Python提取Chrome浏览器保存的密码
Jun 09 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/05/24 PHP
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
JavaScript自动设置IFrame高度的小例子
2013/06/08 Javascript
JS 实现Table相同行的单元格自动合并示例代码
2013/08/27 Javascript
不使用ajax实现无刷新提交表单
2014/12/21 Javascript
javascript中DOM复选框选择用法实例
2015/05/14 Javascript
基于jQuery全屏焦点图左右切换插件responsiveslides
2015/09/07 Javascript
关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
2016/11/30 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
详解webpack es6 to es5支持配置
2017/05/04 Javascript
js单页hash路由原理与应用实战详解
2017/08/14 Javascript
详解NodeJs开发微信公众号
2018/05/25 NodeJs
iconfont的三种使用方式详解
2018/08/05 Javascript
Vue CLI3 如何支持less的方法示例
2018/08/29 Javascript
angularJs利用$scope处理升降序的方法
2018/10/08 Javascript
vue axios请求频繁时取消上一次请求的方法
2018/11/10 Javascript
微信小程序批量监听输入框对按钮样式进行控制的实现代码
2019/10/12 Javascript
vue子传父关于.sync与$emit的实现
2019/11/05 Javascript
详解Nuxt.js 实战集锦
2019/11/19 Javascript
js原生map实现的方法总结
2020/01/19 Javascript
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
[01:02:53]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第二局
2016/03/06 DOTA
[01:11:11]Alliance vs RNG 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
python3制作捧腹网段子页爬虫
2017/02/12 Python
基于python log取对数详解
2018/06/08 Python
Python 共享变量加锁、释放详解
2019/08/28 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
2020/02/26 Python
鲜为人知的HTML5语音合成功能
2019/05/17 HTML / CSS
linux面试题参考答案(5)
2014/09/01 面试题
医学生自我评价
2014/01/27 职场文书
销售员试用期自我评价
2014/09/15 职场文书
行政执法作风整顿剖析材料
2014/10/11 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
react中props 的使用及进行限制的方法
2021/04/28 Javascript
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers
《总之就是很可爱》新作短篇动画《总之就是很可爱~制服~》将于2022年夏天播出
2022/04/07 日漫