2012-09-30 51 views
1

我是所以接近找出一個程序我一直在爲用C編寫的linux shell編寫程序。我一直想讓這個工作一段時間,現在我決定選擇它並且在過去的幾個星期裏一直在修補它。在一個循環中執行多個管道

對於下面的代碼,請記住名爲arrayOfCommand的數組是動態填充的。我的代碼用正在運行的當前命令填充arrayOfCommands。爲了我的例子,我們將運行命令ls -l |廁所和arrayOfCommands充滿以下,這取決於一次循環,它是:

//Pass #1 
arrayOfCommands[]= ("ls", "-l", NULL) 

//Pass #2 
arrayOfCommands[]= ("wc", NULL) 

這是我到目前爲止有:

//PIPING 
int do_command(char **args, int pipes) { 
    // pipes is the number of pipes in the command 
    // (In our example, one) 


    // The number of commands is one more than the 
    // number of pipes (In our example, two) 
    const int commands = pipes + 1; //Ex: 2 
    int i = 0; 

    // Set up the pipes 
    int pipefds[2*pipes]; 

    for(i = 0; i < pipes; i++){ 
     if(pipe(pipefds + i*2) < 0) { 
      perror("Couldn't Pipe"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    // Variables 
    int pid; 
    int status; 
    char *str_ptr; 

    int j = 0; 
    for (i = 0; i < commands; ++i) { 

     // A magic function that updates arrayOfCommands with 
     // the current command goes here. It doesn't make 
     // sense in the context of the code, so just believe me! :) 

     // Ex: The contents will be "ls -l" or "wc" depending on 
     // which time through the loop we are 

     pid = fork(); 

     if(pid == 0) { 
      //if not last command 
      if(i < commands){ 
       if(dup2(pipefds[j + 1], 1) < 0){ 
        perror("dup2"); 
        exit(EXIT_FAILURE); 
       } 
      } 

      //if not first command&& j!= 2*pipes 
      if(j != 0){ 
       if(dup2(pipefds[j-2], 0) < 0){ 
        perror("dup2"); 
        exit(EXIT_FAILURE); 
       } 
      } 

      for(i = 0; i < 2*pipes; i++){ 
        close(pipefds[i]); 
      } 

      // Should any of the below inputs be *arrayOfCommands or 
      // **arrayOfCommands or &arrayOfCommands? 
      // I'm REALLY bad with pointers 

      if(execvp(arrayOfCommands, arrayOfCommands) < 0){ 
        perror(arrayOfCommands); 
        exit(EXIT_FAILURE); 
      } 
     } 
     else if(pid < 0){ 
      perror("error"); 
      exit(EXIT_FAILURE); 
     } 

     j+=2; 
    } 

    for(i = 0; i < 2 * pipes; i++){ 
     close(pipefds[i]); 
    } 

    for(i = 0; i < pipes + 1; i++){ 
    } 
     wait(&status); 
} 

當我運行它,我得到一個幾個錯誤:

  • DUP2:壞的文件描述符
  • LS:|:沒有這樣的文件或目錄
  • LS:WC:沒有這樣的文件或目錄

有人能幫助我弄清楚以下兩件事情:

  1. 爲什麼會出現這些錯誤?
  2. 在execvp函數中,我在尋找什麼類型的指針? arrayOfCommands被初始化爲一個char * arrayOfArgs []
+0

似曾相識。請閱讀:http:// stackoverflow。com/questions/12657430/c-read-from-pipe-blocks-until-child-is-terminated/12661629#12661629然後嘗試按照所述程序 – Serge

回答

2

第一件事:

//if not last command 
if(i < commands) 

應該

if(i < commands -1) 

因爲i0去 應該解決DUP2:錯誤的文件描述符

LS:|:沒有這樣的文件或目錄

LS:WC:沒有這樣的文件或目錄

是由畸形arrayOfCommands引起的。它必須通過

char * arrayOfCommands[] = {"ls", "-l", NULL}; 

char * arrayOfCommands[] = {"wc", NULL}; 

經由execvp(arrayOfCommands[0], arrayOfCommands)

基本上arrayOfCommands必須是一個int main(int argc, char** argv)的相同的格式,你的參數向量(通常argv)分別初始化,並調用。

+0

完美!謝謝! –

相關問題