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中操作日期和时间之gmtime()方法的使用
May 22 Python
一步步解析Python斗牛游戏的概率
Feb 12 Python
在Python程序和Flask框架中使用SQLAlchemy的教程
Jun 06 Python
python使用zip将list转为json的方法
Dec 31 Python
python创建属于自己的单词词库 便于背单词
Jul 30 Python
Django中reverse反转并且传递参数的方法
Aug 06 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
Aug 12 Python
如何使用Python发送HTML格式的邮件
Feb 11 Python
Python中的整除和取模实例
Jun 03 Python
python绘制雷达图实例讲解
Jan 03 Python
python中numpy数组与list相互转换实例方法
Jan 29 Python
Python tkinter之ComboBox(下拉框)的使用简介
Feb 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脚本的10个技巧(1)
2006/10/09 PHP
基于PHP遍历数组的方法汇总分析
2013/06/08 PHP
php中错误处理操作实例分析
2019/08/23 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
2019/10/08 PHP
Javascript 不能释放内存.
2006/09/07 Javascript
js 中 document.createEvent的用法
2010/08/29 Javascript
TextArea不支持maxlength的解决办法(jquery)
2011/09/13 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
JavaScript中双叹号(!!)作用示例介绍
2014/04/10 Javascript
JavaScript的模块化开发框架Sea.js上手指南
2016/05/12 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
Bootstrap实现的标签页内容切换显示效果示例
2017/05/25 Javascript
微信小程序开发animation心跳动画效果
2017/08/16 Javascript
js中document.write和document.writeln的区别
2018/03/11 Javascript
微信小程序 select 下拉框组件功能
2019/09/09 Javascript
Vue 路由间跳转和新开窗口的方式(query、params)
2019/12/25 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
Python解析网页源代码中的115网盘链接实例
2014/09/30 Python
浅析Python中将单词首字母大写的capitalize()方法
2015/05/18 Python
Python3写入文件常用方法实例分析
2015/05/22 Python
Python解析最简单的验证码
2016/01/07 Python
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
python批量读取txt文件为DataFrame的方法
2018/04/03 Python
对python 各种删除文件失败的处理方式分享
2018/04/24 Python
对python中的xlsxwriter库简单分析
2018/05/04 Python
python实现简单名片管理系统
2018/11/30 Python
如何使用pycharm连接Databricks的步骤详解
2020/09/23 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
HTML5 video标签(播放器)学习笔记(一):使用入门
2015/04/24 HTML / CSS
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
Johnston & Murphy官网: 约翰斯顿·墨菲牛津总统鞋
2018/01/09 全球购物
澳大利亚最大的护发和护肤品购物网站:RY
2019/12/26 全球购物
国际会议邀请函范文
2014/01/16 职场文书
社区挂职锻炼个人工作总结
2015/10/23 职场文书
go mod 安装依赖 unkown revision问题的解决方案
2021/05/06 Golang