2016-08-28 23 views
1

我已经写了下面的方法fork和执行由多个管道分隔的命令(测试:ls -lrt | grep“check”| wc -l。但它不会导致任何输出, 。可以在任何一个请找出我的错误感谢C程序来管多个命令

void execCmd (pInfo *info) 
{ 
    int i, j, k, m; 
    struct comType *comm, *comm1, *comm2; 
    if(info->noOfPipes > 2) 
    { 
     // DOES NOT WORK 
     printf("Start\n"); 
     comm=&(info->cArr[0]); 
     comm2=&(info->cArr[(info->ppNum)-1]); 
     int fds[2]; 
     pipe(fds); 
     pid_t pid = fork(); 
     if(pid == -1) 
     { 
      perror("fork failed"); 
      exit(1); 
     } 
     if(pid == 0) 
     { 
      printf("1st child execution here\n"); 
      close(fds[0]); 
      dup2(fds[1], STDOUT_FILENO); 
      close(fds[1]); 
      execvp(comm->cmd,comm->parms); 
     } 
     for (k=1;k<=((info->ppNum)-1);k++) 
     { 
      printf("For loop executionn number %d",k); 
      comm1=&(info->cArr[k]); 
      printf ("comm 1 : %s\n",comm1->cmd); 
      pid = fork(); 
      if(pid == -1) 
      { 
       perror("fork failed"); 
       exit(1); 
      } 
      if(pid == 0) 
      { 
       //2nd to n-1 child process 
       dup2(fds[0], STDIN_FILENO); 
       close(fds[0]); 
       dup2(fds[1], STDOUT_FILENO); 
       close(fds[1]); 
       execvp(comm1->cmd,comm1->parms); 
      } 
      wait(NULL); 
     } 
     pid = fork(); 
     if(pid == -1) 
     { 
      perror("fork failed"); 
      exit(1); 
     } 
     if(pid == 0) 
     { 
      //nth child process 
      printf("Last child execution\n"); 
      close(fds[1]); 
      dup2(fds[0], STDIN_FILENO); 
      close(fds[0]); 
      execvp(comm2->cmd,comm2->parms); 
     } 
     close(fds[0]); 
     close(fds[1]); 
     wait(NULL); 
     wait(NULL); 
    } 
} 
+0

如果您有三个进程,则需要两个管道。我错过了明显的,还是只有一个管道创建? –

+0

'fork'必须在for循环中 – ThunderWiring

回答

0

这下面的代码应该给你一个想法如何实现流水线:

#define STDIN 0 
#define STDOUT 1 
void exec_cmd(struct comType cmd) { 
    execvp(cmd->cmd, cmd->params); 
} 

void pipeCmds(struct comType* cmds) { 
    int fd[cmds_length * 2] = {0}; 
    pid_t pid = 0; 
    for (int i = 0; i < cmds_length; i++) { 
     if (pid = fork() == 0) { 
      //child: make this cmd's output the other cmd's input 
      pipe(fd + (2*i)); 
      close(STDOUT); 
      dup(fd[i]); 
      if(i > 0) { 
       close(STDIN); 
       dup(fd[i-1]); 
      } 
      exec_cmd(cmds[i]); 
      close(fd[i]);   
     } 
    } 
} 

注意,主要思想是每个命令在一个单独的过程中执行(通过fork),并且输出转到下一个命令的输入,而不是转到缺省值stdout(带有文件描述符1),输入转到stdin(文件描述符0)。