我们在执行shell命令比如cat /etc/group | grep root的时候,通过管道的机制将cat /etc/group的结果传递给grep root,然后将结果显示出来
linux中提供了popen和pclose函数来达到这个目的。
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
函数popen先执行fork,然后调用exec以执行command,并且返回一个要么指向子进程的stdout,要么指向stdin的文件指针:若type是”r”,则文件指针是连接到子进程执行command命令的标准输出,如果type是”w”,则文件指针连接到子进程执行command命令的标准输入。那么前面shell命令cat /etc/group | grep root就可以通过下面的程序来实现:
void chapter_15_5_3()
{
    FILE *fpr=NULL,*fpw=NULL;
    char buf[256];
    int ret;
    fpr=popen("cat /etc/group","r");
    fpw=popen("grep root","w");
    while((ret=fread(buf,1,sizeof(buf),fpr)) > 0)
    {
        fwrite(buf,1,ret,fpw);
    }
    pclose(fpr);
    pclose(fpw);
}
执行结果:

那么popen函数是如何工作的呢:

(1) popen(comm, type)函数会创建一个管道,类似与pipe函数创建管道。再fork一个子进程,在子进程中执行execX函数来执行comm命令(因为execX执行新程序后新程序的进程空间会覆盖原进程的进程空间,所以开一个子进程来执行execX家族函数),然后想要返回stdout或者stdin的文件指针(取决于type);

(2) 因为comm命令是通过子进程的执行的,那么stdin或者stdout文件指针也是子进程的进程片空间的,要将其返回给父进程,这就需要通过管道了;

(3) stdin是供程序写数据的,stdout是供程序读数据的。这里设计的巧妙之处在于,管道的读端跟stdout绑定,管道的写端跟stdin绑定;

(4) 读写管道操作的无非就是管道(文件)的fd(文件描述符),这里将fd封装到文件流指针fp中;

在上面的代码中

(1)popen首先创建一个管道,假设为fd。fd[0]指向管道的读端,fd[1]指向管道的写端

(5) popen的type为”r”,返回的是stdout,那么关闭fd[0], 执行shell命令,并写入fd[1]在父进程中关闭fd[1], 将fd[0]转换为一个文件描述符返回。表示创建一个管道且该管道文件的读端赋给fpr。通过fopen可以从fpr中读取数据存入buffer中

(6) popen的type为”w”,返回的是stdin,那么关闭fd[1], 在父进程中关闭fd[0], 将fd[1]转换为一个文件描述符返回表示创建一个管道且该管道文件的写端赋给fpw。通过fwrite()可以从fpw中

(7) 这样子,读fpr(管道的读端)等于读子进程的stdout,写fpw(管道的写端)等于写子进程的stdin。

最新文章

  1. OpenGL实现3D漫游的理解
  2. CentOS7 屏幕亮度的命令行管理
  3. maven 构建一个web项目
  4. Cookie与Session的区别-总结很好的文章
  5. 【转】web集群时session同步的3种方法
  6. Tmux 常用命令与快捷键
  7. lucene 索引流程整理笔记
  8. Poptest学员之当小厨师变成测试开发工程师
  9. 【算法系列学习】巧妙建图,暴搜去重 Counting Cliques
  10. c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信
  11. 使用npm 下载 cnpm
  12. 一文读懂SpringCloud与Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系
  13. Git如何克隆远程仓库
  14. Git 日常工作中使用的命令记录
  15. 刘志梅 201771010115 《面向对象程序设计(java)》 第八周学习总结
  16. MGR架构~单写模式架构的搭建
  17. minidebug学习分析 01 基本框架
  18. Linux 下 SVN服务器搭建
  19. zeebe docker-compose 运行(包含monitor)
  20. 隐藏和显示服务器端控件以及Html控件

热门文章

  1. Android之WebView的使用样例——WebSetting、WebViewClient、WebChromeClient
  2. Node.js 使用jQuery取得Nodejs http服务端返回的JSON数组示例
  3. SQLiteDatabase中query、insert、update、delete方法参数说明
  4. urlib2 标准代码
  5. swift -NavigationController,代理传值
  6. C# DataTable 转 List(大家进来讨论讨论)
  7. Ubuntu14.04下MySQL的安装与卸载
  8. IIS5.1、IIS6.0、IIS7.5中安装配置MVC 3
  9. android tooggle button
  10. jsp页面用java代码取随机数