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 相关文章推荐
python3新特性函数注释Function Annotations用法分析
Jul 28 Python
简单的python后台管理程序
Apr 13 Python
python打包压缩、读取指定目录下的指定类型文件
Apr 12 Python
Python3中的json模块使用详解
May 05 Python
python调用Matplotlib绘制分布点并且添加标签
May 31 Python
对python借助百度云API对评论进行观点抽取的方法详解
Feb 21 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
May 05 Python
django框架model orM使用字典作为参数,保存数据的方法分析
Jun 24 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
Django 静态文件配置过程详解
Jul 23 Python
浅谈python多线程和多线程变量共享问题介绍
Apr 17 Python
将不规则的Python多维数组拉平到一维的方法实现
Jan 11 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
smarty自定义函数用法示例
2016/05/20 PHP
PHP 网站修改默认访问文件的nginx配置
2017/05/27 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
实例讲解PHP中使用命名空间
2019/01/27 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
使用正则替换变量
2007/05/05 Javascript
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
javascript中文本框中输入法切换的问题
2013/12/10 Javascript
JavaScript获取客户端计算机硬件及系统等信息的方法
2014/01/02 Javascript
使用js显示当前时间示例
2014/03/02 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
深入浅析AngularJS中的module(模块)
2016/01/04 Javascript
Javascript动画效果(2)
2016/10/11 Javascript
AngularJS执行流程详解
2017/02/17 Javascript
微信小程序图片选择区域裁剪实现方法
2017/12/02 Javascript
使用FileReader API创建Vue文件阅读器组件
2018/04/03 Javascript
vue异步axios获取的数据渲染到页面的方法
2018/08/09 Javascript
vuex 解决报错this.$store.commit is not a function的方法
2018/12/17 Javascript
JS中min函数实例讲解
2019/02/18 Javascript
在vue中实现echarts随窗体变化
2020/07/27 Javascript
nuxt 服务器渲染动态设置 title和seo关键字的操作
2020/11/05 Javascript
Python实现简单过滤文本段的方法
2017/05/24 Python
python基础教程项目四之新闻聚合
2018/04/02 Python
详解python3中tkinter知识点
2018/06/21 Python
pandas修改DataFrame列名的实现方法
2019/02/22 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
python 计算概率密度、累计分布、逆函数的例子
2020/02/25 Python
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
介绍一下游标
2012/01/10 面试题
机电专业个人求职信范文
2013/12/30 职场文书
大学生期末自我鉴定
2014/02/01 职场文书
学生手册家长评语
2014/02/10 职场文书
2015年行政部工作总结
2015/04/28 职场文书
催款函范文
2015/06/24 职场文书
Python如何用re模块实现简易tokenizer
2022/05/02 Python