2011-08-15 57 views
0

我想在c中編寫一個shell,它主要工作,除了grep。每當我在shell中給出一個grep命令時,它都不會輸出任何內容。下面是我用來創建一個新的子進程,然後在其中運行execvp()的代碼部分。grep不能在自定義shell中工作

dup2中的文件描述符(fd_in和fd_out)作爲參數傳遞給具有此代碼的函數。最有趣的是,當我給'grep'或'grep --help'時,它照常顯示。我錯過了什麼?或者用grep做一些特別的事情?

這就是我的shell所發生的情況:當從bash運行時,最後一個命令輸出。

--> grep 
Usage: grep [OPTION]... PATTERN [FILE]... 
Try `grep --help' for more information. 
--> wc /etc/hosts 
11 33 314 /etc/hosts 
--> grep -i "perror" shell.c 
--> 

下面是代碼:

void 
create_process(char *cmd_argv[], int fd_in, int fd_out, char *buffer_copy) { 

    /*Flag bit for Background processes*/ 
    int FLAG = 0; 

    pid_t cpid; 
    int status; 
    int i = 0,j = 0; 

    /*Find the no. of arguments*/ 
    while(cmd_argv[j] != NULL) 
     j++; 

    /*Set the flag bit*/ 
    if(strcmp("&", cmd_argv[j-1]) == 0) { 
     FLAG = 1; 
     cmd_argv[j-1] = NULL; 
    } 

    //Create a child process 
    cpid = fork(); 

    if (cpid == -1) { 
     perror("fork"); 
     exit(EXIT_FAILURE); 
    } 

    //In the child... 
    if (cpid == 0) { 

    /*Checking if the file descriptors are already assigned*/ 

     /*For stdin*/ 
     if (fd_in != STDIN_FILENO) { 
      dup2(fd_in, STDIN_FILENO); 
      close(fd_in); 
     } 

     /*For stdout*/ 
     if (fd_out != STDOUT_FILENO) { 
      dup2(fd_out, STDOUT_FILENO); 
      close(fd_out); 
     } 

     /*Run the cmd specified*/ 
     status = execvp(cmd_argv[0], cmd_argv); 

     /*In case of errors*/ 
     if(status < 0) { 
      perror("execvp "); 
      exit(1); 
     } 
    } 

    //In the parent... 
    else { 

     if(FLAG == 1) { 
      /*Find where the new bg process can be inserted*/ 
      while(1) { 
       if (bgprocess[i].pid == 0) { 
        bgprocess[i].pid = cpid; 
        strcpy(bgprocess[i].cmd, buffer_copy); 
        break; 
       } 
       i++; 
      } 
      printf("[%d] : %s\n", cpid, cmd_argv[0]); 
     } 

     /*If not bg, wait for the process to exit*/ 
     else 
      waitpid(cpid, NULL, 0); 
    } 
} 
+0

向我們展示如何設置'cmd_argv'。 – cnicutar

+0

char * cmd_argv [10];代碼的前一部分用適當的參數填充,然後是NULL。當你運行grep時, – 0x777

+0

顯示你的shell的一個strace。另外,你應該關心stderr以及stdin/stdout。 – nos

回答

0

問題是在你的shell中使用引號。 Bash在後臺做了很多事情。 grep -i perror shell.c應該給你的shell輸出,無論從bash運行時的預期如何。

0

答曰man dup2

從這些系統調用之一,老 新文件描述符成功返回後可以互換使用。他們指的是 同一個打開的文件說明(請參閱open(2))...

因此後後您的來電DUP2(你應該檢查的錯誤返回)關閉oldfdnewfd因爲它們是精確相同的描述符。

我不明白的是爲什麼grep --help可以工作,但是你沒有顯示足夠的代碼來回答這個問題。

增加了以下評論:您仍然沒有提供足夠的代碼。如果grep不工作比什麼是? wc /etc/hosts是否工作?關於grep沒有什麼特別的,它確實是一個完全沒有特別要求的Unix過濾器。

+0

使用完整的fn代碼編輯主帖子 – 0x777

+0

不,不可以,你可以在不影響底層文件description的情況下關閉一個descripTOR文件 - 否則你將無法因爲stdout和stderr最初引用的是相同的打開文件,所以你必須先關閉fd 1,然後才能將某些東西拷貝到它上面),但是所有_else_但close都會影響底層文件的描述 –

+0

已更新在主帖中輸出我的shell。 – 0x777