2010-04-07 82 views
2

可以說我的程序中我想執行兩個子進程,一個執行「ls -al」命令,然後將其傳送到「wc」命令並在終端上顯示輸出。我怎樣才能做到這一點使用管道文件描述符到目前爲止,我寫的代碼:一個例子是大大有益的使用fork和dup的Unix管道

int main(int argc, char *argv[]) { 
    int pipefd[2]; 
    int pipefd2[2]; 

    pipe(pipefd2); 
    if ((fork()) == 0) { 
     dup2(pipefd2[1],STDOUT_FILENO); 
     close(pipefd2[0]); 
     close(pipefd2[1]); 
     execl("ls", "ls","-al", NULL); 
     exit(EXIT_FAILURE); 
    } 

    if ((fork()) == 0){ 
     dup2(pipefd2[0],STDIN_FILENO); 
     close(pipefd2[0]); 
     close(pipefd2[1]); 
     execl("/usr/bin/wc","wc",NULL); 
     exit(EXIT_FAILURE); 
    } 
    close(pipefd[0]); 
    close(pipefd[1]); 
    close(pipefd2[0]); 
    close(pipefd2[1]); 
} 

回答

10

你的示例代碼是語法和語義損壞(如pipefd2不decared,pipefd和pipefd2之間的混淆,等等)由於這種味道像家庭作業,請確保您瞭解我的註釋,並詢問更多您是否需要。我已經忽略了對pipe,fork和dup的錯誤檢查,但理想情況下它們應該在那裏。

int main(int argc, char *argv[]) { 
    int pipefd[2]; 
    pid_t ls_pid, wc_pid; 

    pipe(pipefd); 

    // this child is generating output to the pipe 
    // 
    if ((ls_pid = fork()) == 0) { 
     // attach stdout to the left side of pipe 
     // and inherit stdin and stdout from parent 
     dup2(pipefd[1],STDOUT_FILENO); 
     close(pipefd[0]);    // not using the right side 

     execl("/bin/ls", "ls","-al", NULL); 
     perror("exec ls failed"); 
     exit(EXIT_FAILURE); 
    } 

    // this child is consuming input from the pipe 
    // 
    if ((wc_pid = fork()) == 0) { 
     // attach stdin to the right side of pipe 
     // and inherit stdout and stderr from parent 
     dup2(pipefd[0], STDIN_FILENO); 

     close(pipefd[1]);    // not using the left side 
     execl("/usr/bin/wc", "wc", NULL); 
     perror("exec wc failed"); 
     exit(EXIT_FAILURE); 
    } 

    // explicitly not waiting for ls_pid here 
    // wc_pid isn't even my child, it belongs to ls_pid 

    return EXIT_SUCCESS; 
} 
+1

關閉一個'dup''d文件描述符關閉另一個是**不是**。關閉只是刪除打開文件的一個句柄。文件本身在所有的'dup''d文件描述符都關閉之前不會關閉。 – caf 2010-04-07 07:42:10

+1

哦,你*應該關閉父文件中的'pipefd'文件描述符 - 它不需要它們(並且直到父文件在寫入結束時關閉它的句柄,閱讀子文件纔會看到文件結束) 。同樣,'close()'只能刪除你傳遞它的句柄,直到* every *進程中的所有句柄都關閉,底層管道纔會關閉。 – caf 2010-04-07 07:49:35

+1

你是多麼的正確,咖啡,更正,謝謝。 – msw 2010-04-07 12:33:42