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使用7z解压软件备份文件脚本分享
Feb 21 Python
对于Python编程中一些重用与缩减的建议
Apr 14 Python
python3.5实现socket通讯示例(TCP)
Feb 07 Python
教你使用python画一朵花送女朋友
Mar 29 Python
Python面向对象之类和实例用法分析
Jun 08 Python
Windows下python3安装tkinter的问题及解决方法
Jan 06 Python
python3连接mysql获取ansible动态inventory脚本
Jan 19 Python
python 中的[:-1]和[::-1]的具体使用
Feb 13 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
Jul 03 Python
python 如何用map()函数创建多线程任务
Apr 07 Python
OpenCV绘制圆端矩形的示例代码
Aug 30 Python
如何利用python创作字符画
Jun 25 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 Cookie的一个使用注意点
2008/11/08 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
2011/06/28 PHP
PHP实现的曲线统计图表示例
2016/11/10 PHP
一段非常简单的让图片自动切换js代码
2006/11/10 Javascript
基于jquery的监控数据是否发生改变
2011/04/11 Javascript
javascript在myeclipse中报错的解决方法
2013/10/29 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
2013/11/28 Javascript
直接在JS里创建JSON数据然后遍历使用
2014/07/25 Javascript
AngularJS基础知识
2014/12/21 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
2015/02/17 Javascript
JS延时提示框实现方法详解
2015/11/26 Javascript
Bootstrap精简教程中秋大放送
2016/09/15 Javascript
微信小程序 scroll-view组件实现列表页实例代码
2016/12/14 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
2017/01/05 Javascript
Javascript的this用法
2017/01/16 Javascript
javascript 秒表计时器实现代码
2017/03/09 Javascript
jquery append与appendTo方法比较
2017/05/24 jQuery
jQuery+Ajax请求本地数据加载商品列表页并跳转详情页的实现方法
2017/07/12 jQuery
Nodejs调用WebService的示例代码
2017/09/29 NodeJs
微信小程序使用canvas的画图操作示例
2019/01/18 Javascript
Python 自动补全(vim)
2014/11/30 Python
详解Python爬虫的基本写法
2016/01/08 Python
python生成词云的实现方法(推荐)
2017/06/13 Python
python数据封装json格式数据
2018/03/04 Python
Python3编码问题 Unicode utf-8 bytes互转方法
2018/10/26 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
python 工具 字符串转numpy浮点数组的实现
2020/03/14 Python
Django 删除upload_to文件的步骤
2020/03/30 Python
通信工程毕业生自荐信
2013/11/01 职场文书
广告设计专业自荐信范文
2013/11/14 职场文书
舞蹈教育学专业推荐信
2013/11/27 职场文书
经典安踏广告词
2014/03/21 职场文书
学生社团文化节开幕式主持词
2014/03/28 职场文书
房地产公司财务总监岗位职责
2015/04/03 职场文书
毕业晚宴祝酒词
2015/08/11 职场文书