2016-08-28 19 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)。