2015-05-13 81 views
0

我試圖模擬Ubuntu終端上的管道行爲,例如命令:
「echo hello | wc」。
請假設我從stdin獲得了令牌,正確處理了所有內容,現在這些是我從用戶輸入的命令,我在shell中鍵入它們以供我處理。
我正在嘗試創建兩個進程。在第一個過程中,使用管道將管道寫入邊緣的文件描述符指向stdout。第二個進程應讀入標準輸入讀取管道的讀取邊緣execvp(..)返回的內容。
這裏是我寫的代碼:在Ubuntu的殼處理中的特定管道命令C

#include <stdio.h> 
#include <stdlib.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int main() 
{ 
    char* fcmd[] = {"echo", "hello", NULL}; 
    char* scmd[] = {"wc", NULL}; 
    pid_t pid; 
    int pipe_des[2]; 
    int i; 
    pipe(pipe_des); 
    for(i = 0; i < 2; i++) 
    { 
     pid = fork(); 
     if (pid ==0) 
     { 
      switch (i) 
      { 
       case 0: // FIRST CHILD 
       { 
        dup2(pipe_des[1], STDOUT_FILENO); 
        close(pipe_des[0]); 
        execvp(fcmd[0], fcmd); 
        exit(0); 
       } 
       case 1: //SECOND CHILD 
       { 
        dup2(pipe_des[0], STDIN_FILENO); 
        close(pipe_des[1]); 
        execvp(scmd[0], scmd); 
        exit(0); 
       } 
      } 
     } 
     else if (pid < 0) 
      exit(EXIT_FAILURE); 
return EXIT_SUCCESS; 
} 

我得到:「[email protected]:~/Desktop/os/class/ex4$ 1 1 6
像它應該,但爲什麼他第一次印刷的bash CWD?根據我使用echo命令發送的單詞的長度(在main()中),管道似乎工作,因爲我得到了我應該做的。之後,光標在下面的行中等待另一個命令,而不顯示bash pwd。 (也許stdin正在等待?)
我看過很多帖子在這裏以及在其他網站上,我仍然無法找到解決我的問題。任何幫助,將不勝感激。提前致謝。 注意:請忽略檢查錯誤,我已經刪除它們以使代碼更短,所以假設它們存在。

回答

1

爲什麼在輸出之前得到提示?

您的主要過程不會等待孩子完成。你看到的是:

  1. 主開始
  2. 主要創建兒童
  3. 主要退出
  4. BASH打印提示
  5. 兒童開始工作

爲了防止這種情況,你需要等待孩子們。見How to wait until all child processes called by fork() complete?

在你的情況,這足以在循環後添加

waitpid(-1, NULL, 0); 

+0

你說什麼解決了一切,我只需要等待。我添加了「waitpid(-1,NULL,0);」 for循環之後,它的工作原理!謝謝! –