2016-12-20 152 views
0

我是新StackOverflow上和學習有關C.管我試圖做出允許通過引入管道連接2個命令,如管道執行命令只有一次

/bin/ls -l | /bin/grep a 

我有一個主殼interpeter它具有讀取命令的功能,然後main調用一個函數來搜索「|」如果它找到它,那麼該函數會從中產生2個命令,然後該函數會調用另一個執行這些命令的命令。我的問題是,它只是一次。如果我用管道引入一個命令,它可以完美地執行它,但是如果我再次執行它,它不起作用,就像目錄有變化一樣。不管第一個命令是否有管道,第二個命令(如果它有管道)都不會正確執行。我想這是因爲管道中,該功能的代碼執行管:

void execute_pipes(char *** command1, char *** command2){ 
pid_t son; 
int tube2[2]; 
pipe(tube2); 
son=fork(); 
if(son==0){//son1 
    dup2(tube2[1], STDOUT_FILENO); 
    close(tube2[0]); 

    if(execv((*command1)[0],*command1)==-1){ 
     printf("Error"); 
     exit(0); 
    } 
}else{//father 
    son=fork(); 
    if(son==0){//son2 
     dup2(tube2[0], STDIN_FILENO); 
     close(tube2[1]); 


     if(execv((*command2)[0],*command2)==-1){ 
      printf("Error"); 
      exit(0); 
     } 
    }else{//father 
     close(tube2[0]); 
     close(tube2[1]); 
     waitpid(son, NULL, 0); 


    } 
} 
} 

我敢肯定,這些參數都OK,用NULL參數結束(如果不是我想這難道不執行一次)。在每次新讀取中,都會創建一個新管道。我想這最後的管道不會影響這個新的,但我不知道...... 這樣的一個例子:

/home/user/Desktop$ /bin/ls -l | /bin/grep - 
-rw-rw-r-- 1 user user  435 dec 18 02:33 filename 
drwxrwsr-x 9 user user  4096 dec 20 19:23 filename 
-rwxrwxr-x 1 user user 14464 dec 20 20:29 filename 
-rw-rw-r-- 1 user user 3580430 dec 5 03:24 filename 
-rw-rw-r-- 1 user user  6833 dec 20 20:05 filename 
-rw-rw-r-- 1 user user  6772 dec 20 18:48 filename 
-rw-rw-r-- 1 user user  1226 dec 19 21:48 filename 
-rwxrwxr-x 1 user user  8704 dec 18 16:23 filename 
-rw-rw-r-- 1 user user 33673847 oct 17 20:50 filename 
/home/user/Desktop$ /bin/ls -l | /bin/grep - 
-rwxr-xr-x 1 root root 126584 feb 18 2016 /bin/ls 
/home/user/Desktop$ 

注:我改變了我的用戶名「用戶」和姓名'文件名'的文件。 謝謝無論誰讀這個。 總結:我的代碼只執行一次正確的命令,第二次它不能正常工作,我不知道爲什麼,但我想問題是管道。

+0

您需要將第一個stdout掛鉤到第二個。我在代碼中沒有看到任何地方 –

+0

歡迎來到本網站!你能否請[編輯你的問題](https://stackoverflow.com/posts/41250027/edit)澄清究竟是什麼問題?我不知道。我確實看到你的'dup2'調用將管道掛接到stdin/stdout。一個想法 - 你只給一個孩子叫'waitpid'。你可以嘗試'waitpid(-1,...'在一個循環中等待兩個孩子在父母退出之前。不知道這是否重要,但它不會傷害嘗試。 - 另外,檢查[遊覽](https://stackoverflow.com/tour)關於該網站的更多信息! – cxw

+0

完成後,我在最後添加了它,我試圖等待兩次,但結果是一樣的感謝有關旅遊信息和回答我! –

回答

0

我還不能評論,所以我發佈它作爲答案。歡迎來到SO。如果你提供一個我認爲你可以做的實例,人們會更容易幫助你。這裏是一個指南How to create a Minimal, Complete, and Verifiable example

不幸的是我不能讓你的代碼工作。也許看一個輕量級shell的示例實現可以幫助你。 Here是xv6 shell的源代碼。搜索PIPE關鍵字。

XV6是重新實施丹尼斯里奇的和肯·湯普森的Unix版本 6(V6)。

+0

問題是,我不得不把這作爲家庭作業,我害怕有人可以複製它。無論如何,非常感謝關於xv6的信息,它看起來非常有用。 –

+0

@ YoloD.Haksel:如果你的代碼不應該顯示,你不應該問這個問題。除此之外,如果你得到答案然後刪除問題,你就會違背SO的精神。如果你的學術道德沒有被清除,那麼最好刪除這個問題,而不是留下足夠長的時間來得到答案,然後刪除它。 –

+0

@pbn我不應該顯示它的每一個部分,但我猜一些部分可以顯示。現在已經晚了,刪除這個,但我會更加小心下次,謝謝你的信息! –

0

奧克,我解決了這個問題,這是一個初始化參數的問題。這是我沒有寫的功能,因爲我認爲它工作。 我現在唯一的疑問是爲什麼甚至能夠執行... 謝謝大家回答我。