首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

linux pipe "实现 ls |grep hello|grep world "该如何解决

2012-05-09 
linux pipe实现 ls |grep hello|grep world 代码不知哪出错了。C/C++ code#include stdio.h#include s

linux pipe "实现 ls |grep hello|grep world "
代码不知哪出错了。

C/C++ code
#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */void exec(){  int fd[2];  int fd2[2];  pid_t pid;  char str[10];  char* cmd[3]={"ls","grep","grep"};  char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};  int i;  pipe(fd);  pipe(fd2);  pid=fork();  if(pid==0){                    /* child */    dup2(fd[1],STDOUT_FILENO);    close(fd[0]);    close(fd2[0]);    close(fd2[1]);    execvp(cmd[0],params[0]);   /* ls -l */    exit(1);  }  if(pid>0){    pid=fork();    if(pid==0){      dup2(fd[0],STDIN_FILENO);      close(fd[1]);      dup2(fd2[1],STDOUT_FILENO);      close(fd2[0]);      execvp(cmd[1],params[1]); /* grep fork */      exit(1);    }    /* dup2(0,STDIN_FILENO); */    /* dup2(1,STDOUT_FILENO); */    pid=fork();    if(pid==0){      dup2(fd2[0],STDIN_FILENO);      close(fd2[1]);      /* printf ("%s\n",cmd[2]); */      execvp(cmd[2],params[2]); /* grep 2 */      exit(1);    }    close(fd[0]);    close(fd[1]);    close(fd2[0]);    close(fd2[1]);  }}int main(int argc, char *argv[]){  exec();  return 0;}

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/*利用 管道,写一个类似 ls -l |grep fork|grep 2的程序 , */
void exec(){
  int fd[2];
  int fd2[2];
  pid_t pid;
  char str[10];
  char* cmd[3]={"ls","grep","grep"};
  char* params[3][3]={{"ls","-l",NULL},{"grep","fork",NULL},{"grep","2",NULL}};
  int i;
  pipe(fd);
  pipe(fd2);
  pid=fork();
  if(pid==0){ /* child */
  dup2(fd[1],STDOUT_FILENO);
  close(fd[0]);
  close(fd2[0]);
  close(fd2[1]);
  execvp(cmd[0],params[0]); /* ls -l */
  exit(1);
  }
  if(pid>0){
  pid=fork();
  if(pid==0){
  dup2(fd[0],STDIN_FILENO);
  close(fd[1]);
  dup2(fd2[1],STDOUT_FILENO);
  close(fd2[0]);
  execvp(cmd[1],params[1]); /* grep fork */
  exit(1);
  }

  /* dup2(0,STDIN_FILENO); */
  /* dup2(1,STDOUT_FILENO); */
  pid=fork();
  if(pid==0){
  dup2(fd2[0],STDIN_FILENO);
  close(fd2[1]);
  /* printf ("%s\n",cmd[2]); */
  execvp(cmd[2],params[2]); /* grep 2 */
  exit(1);
  }

  close(fd[0]);
  close(fd[1]);
  close(fd2[0]);
  close(fd2[1]);
  }


}
int main(int argc, char *argv[]){
  exec();
  return 0;
}


[解决办法]
先关掉STDOUT_FILENO,否则dup2会复制到比STDOUT_FILENO大的最小的空闲fd
[解决办法]
否则标准输入输出就没变
[解决办法]
关闭fd[1]就可以了。可能是同时两个管道在STDOUT_FILENO上导致的问题。
[解决办法]
fd2对于ls进程就没用,应该在grep fork进程创建,逻辑关系本来就是ls关联grep fork,grep fork关联grep 2,你倒写成了ls关联grep fork & grep 2,有悖逻辑吧。

 另外ls进程没有close(fd[1]),grep进程始终读不到EOF。



[解决办法]
以前修改过一个类似的问题,参考一下吧

C/C++ code
#include <stdio.h>#include <unistd.h>#include <sys/wait.h>int main(){    pid_t pid[3];    int pipe_fd[2];    int pipe_fd2[2];    int status;    char *prog1[3] = {"/bin/ls", "-l", NULL};    char *prog2[3] = {"/bin/grep", "cpp", NULL};    char *prog3[3] = {"/bin/grep", "2", NULL};    if (pipe(pipe_fd) < 0) {        perror("pipe 1 failed");    }    if (pipe(pipe_fd2) < 0) {        perror("pipe 2 failed");    }    if ((pid[0] = fork()) < 0) {        perror("fork failed");    }    if (pid[0] == 0) {        close(pipe_fd[0]);        dup2(pipe_fd[1], 1);        close(pipe_fd[1]);        close(pipe_fd2[0]);        close(pipe_fd2[1]);        execvp(prog1[0], prog1);    }    if (pid[0] > 0) {        pid[1] = fork();        if (pid[1] == 0) {            close(pipe_fd[1]);            dup2(pipe_fd[0], 0);            close(pipe_fd[0]);            close(pipe_fd2[0]);            dup2(pipe_fd2[1], 1);            close(pipe_fd2[1]);            execvp(prog2[0], prog2);        }        if (pid[1]>0) {            pid[2] = fork();            if (pid[2] == 0) {                close(pipe_fd2[1]);                dup2(pipe_fd2[0], 0);                close(pipe_fd2[0]);                close(pipe_fd[0]);                close(pipe_fd[1]);                execvp(prog3[0], prog3);            }        }        close(pipe_fd[0]);        close(pipe_fd[1]);        close(pipe_fd2[0]);        close(pipe_fd2[1]);        waitpid(pid[1], &status, 0);    }    return 0;}
[解决办法]
不同的fd共享同一个文件表项,只有所有共享同一表项的fd全部close,才会令read该fd的返回0,否则子进程就是无限的等待read。

热点排行