zoukankan      html  css  js  c++  java
  • 19重定向管道与popen模型

    重定向 dup2

    int dup(int fd)

    重定向文件描述符  int newFd = dup(STDOUT_FILENO)

    newFd 指向 stdout

    int dup2(int fd1, int fd2)

    重定向文件描述符  dup2(newFd, STDOUT_FILENO)

    stdout 指向 newFd

    重定向输入输出到管道

    例子1: 父进程标准输入后,有子进程进行标准输出

    void testDup()

    {

          int fds[2];

          pid_t pid;

          char buf[128];

          if(pipe(fds))

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail pipe!");

               return ;

          }

          pid=fork();

          if(pid<0)

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail fork!");

               return ;

          }

          else if(pid==0)

          {

               close(fds[1]);

               //直接输出

               dup2(STDOUT_FILENO,fds[0]);  

          }

          else

          {

               close(fds[0]);

               dup2(STDIN_FILENO,fds[1]);

               //父进程接受键盘输入

               while(1)

               {

               fprintf(stderr,"parent send:");

               memset(buf,0,sizeof(buf));

               read(STDIN_FILENO,buf,sizeof(buf));

               write(fds[1],buf,strlen(buf));

               }

               close(fds[1]);

          }

          return ;

    }

    例子2: ls | more 类似实现

    思路:

    1.ls 的输出,是输出到  STDOUT

    2.more 的输入,是从 STDIN 接受

    3.我们要实现 ls 的输出,作为 more 的输入

    4.所以我们要创建管道,然后,把 STDOUT 和 STDIN 重定向到管道

    5.这样 我们就实现了: 连接 ls 和 more

    void testDup2()

    {

          int fds[2];

          pid_t pid;

          if(pipe(fds))

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail pipe!");

               return ;

          }

          pid=fork();

          if(pid<0)

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail fork!");

               return ;

          }

          else if(pid==0)

          {

               close(fds[1]);

               dup2(fds[0],STDIN_FILENO);

               printf(" ");

               execlp("more","more","-d",NULL);

              

               close(fds[0]);

          }

          else

          {

               close(fds[0]);

              

               dup2(fds[1],STDOUT_FILENO);

               execlp("ls","ls","-b",NULL);

               close(fds[1]);

          }

    }

    popen 模型

    FILE *popen(const char *cmd, char *type)

    解析:

    创建子进程,并调用exec,指向cmd命令

    同时建立管道,用于父子进程标准输入输出

    type取值 “ r ” :       数据由子进程流到父进程

    type取值 “ w ”:       数据由父进程流到子进程

    int   pclose(FILE *stream)

    popen第一参数与exec的区别:

    popen第一参数包括了命令的名称,参数。如:popen(”ps -ef”,”r”)作为第一参数。

    exec是路径、名称、参数分开多个部分作为exec的参数传入。如exec(“ps”,”ps”,”-ef”);

    例子:排序

    void testPopen()

    {

          int arr[]={2,4,5,77,11,22,633,21,4};

          FILE *file=popen("sort -n","w");

          if(!file)

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail open file!");

               return ;

          }

          int i=0;

          for(;i<sizeof(arr)/sizeof(arr[0]);++i)

          {

               fprintf(file,"%d ",arr[i]);

          }

          pclose(file);

    }

    例子2:通过 popen 实现  ps -ef | grep pts

    思路:

    1.使用popen模型分别调用ps –ef, grep pts:

    pRead = popen("ps -ef", "r")

    pWrite= popen("grep pts", "w")

    2.此时pRead,pWrite就是两个文件指针,进行文件读写操作。

    3. 从 pRead中读取数据,写入到 pWrite中。

    void testPopen2()

    {

          FILE *pRead=popen("ps -ef","r");

          FILE *pWrite=popen("grep pts","w");

          if(!(pRead&&pWrite))

          {

               printf("file:%s,line:%d",__FILE__,__LINE__);

               perror("fail open file!");

               return ;

          }

          char buf[1024];

          while(fgets(buf,sizeof(buf),pRead))  

          {

               fputs(buf,pWrite);

          }

          pclose(pRead);

          pclose(pWrite);

    }

  • 相关阅读:
    MySQL-DQL查询语句的其他方法查询
    MySQL-SQL的分类以及基本的操作
    1-1-4-2 Java se-常量&变量-作用域
    1-1-4-1 java se-常量&变量-基本数据类型
    1-1-2-1 java se-helloworld原理—java代码的编译和运行逻辑
    1-1-1-2 Java se-java运行环境-jvm虚拟机的跨平台性以及和jdk,jre之间的关系
    1-1-1-1 java se-java运行环境-基本单位bit和Byte
    递归
    Ultra-QuickSort (POJ 2299)树状数组+离散化
    Color the ball(HDU1556)树状数组
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216010.html
Copyright © 2011-2022 走看看