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 15 Python
浅谈Python数据类型之间的转换
Jun 08 Python
浅谈python字符串方法的简单使用
Jul 18 Python
python异常和文件处理机制详解
Jul 19 Python
浅析python中的分片与截断序列
Aug 09 Python
python遍历 truple list dictionary的几种方法总结
Sep 11 Python
详解python中requirements.txt的一切
Mar 03 Python
python最长回文串算法
Jun 04 Python
IntelliJ IDEA安装运行python插件方法
Dec 10 Python
python传到前端的数据,双引号被转义的问题
Apr 03 Python
python中os包的用法
Jun 01 Python
基于Python编写一个计算器程序,实现简单的加减乘除和取余二元运算
Aug 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源码加密 仿微盾PHP加密专家(PHPCodeLock)
2010/05/06 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
PHP引用返回用法示例
2016/05/28 PHP
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
2015/08/11 Javascript
js实现将选中值累加到文本框的方法
2015/08/12 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
2017/07/07 Javascript
H5基于iScroll实现下拉刷新和上拉加载更多
2017/07/18 Javascript
JS写谷歌浏览器chrome的外挂实例
2018/01/11 Javascript
vue.js 获取select中的value实例
2018/03/01 Javascript
Node.js中读取TXT文件内容fs.readFile()用法
2018/10/10 Javascript
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
JS数组的高级使用方法示例小结
2020/03/14 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
Node.js web 应用如何封装到Docker容器中
2020/09/01 Javascript
解决antd 下拉框 input [defaultValue] 的值的问题
2020/10/31 Javascript
python实现下载文件的三种方法
2017/02/09 Python
python3 图片referer防盗链的实现方法
2018/03/12 Python
Python内存读写操作示例
2018/07/18 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
详解Django admin高级用法
2019/11/06 Python
Python Tkinter模块 GUI 可视化实例
2019/11/20 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
Pandas把dataframe或series转换成list的方法
2020/06/14 Python
如何编写python的daemon程序
2021/01/07 Python
世界上最大的艺术和工艺用品商店:MisterArt.com
2018/07/13 全球购物
李维斯牛仔裤荷兰官方网站:Levi’s NL
2020/08/23 全球购物
Ruby如何进行文件操作
2014/07/17 面试题
门卫岗位安全职责
2013/12/13 职场文书
八一建军节部队活动方案
2014/02/04 职场文书
2014年小学生教师节演讲稿范文
2014/09/10 职场文书
党风廉正建设责任书
2015/01/29 职场文书
Redis实战之Lettuce的使用技巧详解
2022/12/24 Redis