在linux上 重新導向 管道實現

來源:互聯網
上載者:User

管道和重新導向

輸入輸出不僅可以重新導向到檔案,也可以通過管道傳遞到其他進程中。

基本思路:

linux:

1. 建立管道對

pipe(int pipefd[2])

2. 建立進程

首先fork,然後子進程用dup2把pipefd[0]複製到STDIN_FILENO(就是0),然後關閉pipefd[1],或者把pipefd[1]複製到STDOUT_FILENO(就是1),然後關閉pipefd[0]。

之後調用exec去載入要建立的進程。

3. 讀或寫

用read或者write。注意讀寫之前要把子進程使用的那一個用close函數關閉掉。

區別在*nix建立進程分兩步,fork然後exec。windows只一步。

區別2,*nix要手工dup來複製檔案描述符,windows在建立進程的API內部做好了這件事。

linux步驟多一些,但是靈活,可以變化出多種模式來,例如fork之後,不僅僅子進程可以exec,父進程也可以exec,完完全全實現像“ls|wc -l”這樣的功能。也就是子進程用wc去替代,父進程用ls去替代。

windows步驟少,模式固定,它要實現上述功能,反而更加繁瑣,需要建立兩個進程,並把它們對接,然後等待兩個進程結束

執行個體:

題目:通過管道類比shell命令:catfile | sort

涉及主要知識點:未具名管道、重新導向

題目描述:具體類比一個shell命令:cat file | sort。具體的一些提示在後面。

提示:首先在目前的目錄下建立一個名為”file”的檔案,裡面的內容輸入如下:

99

123

892

12

1342

89

32

76

通過執行”cat file | sort”後的結果如下:

12

123

1342

32

76

89

892

99

現在我們需要通過一個管道,將”cat file”的結果通過管道送給命令”sort”。其中,將”cat file”命令的輸出結果重新導向到”sort”命令的輸入是由包含在命令中的管道標誌”|”來完成的。為了在程式當中實作類別似的功能,需要用dup()或者dup2()系統調用將標準輸入和標準輸出聯絡起來,具體的系統調用使用可以通過man手冊來查,或者查閱群共用裡面的函數手冊。另外,這裡的”cat file”和”sort”命令不是自己來完成,而是通過調用exec函數族來實現的。

******************************************************************************************************************************************

******************************************************************************************************************************************

我的原始碼如下:

  

1 #include <stdio.h>  2 #include<stdlib.h>  3 #include<string.h>  4 #include<unistd.h>  5 #include<sys/types.h>  6 #include<sys/stat.h>  7  8 int main(intarg,char *argv[],char **environ)  9 { 10     int fd[2]; 11     pid_t pid; 12     int stat_val; 13 14     if(arg < 2) 15     { 16         printf("wrong parameters\n"); 17         exit(0); 18     } 19     if(pipe(fd)) 20     { 21         printf("Create pipefailed!\n"); 22         exit(1); 23     } 24 25     pid=fork(); 26     switch(pid) 27     { 28         case -1: 29             perror("forkfailed!\n"); 30             exit(1); 31         case 0: 32             //close(0); 33             //dup(fd[0]); 34             dup2(fd[1],1); 35             close(fd[0]); 36             execlp("cat","cat","file",NULL); 37             exit(0); 38         default: 39             dup2(fd[0],0); 40             close(fd[1]); 41             execlp("sort","sort",NULL); 42             exit(0); 43     } 44     wait(&stat_val); 45     exit(0); 46     return 0; 47 }************************************************************************************************************************************************************************************************************************************************************************************編譯sort.c:jingjing@jingjing-laptop:~/公用的$ gccsort.c -o sort 運行程式:jingjing@jingjing-laptop:~/公用的$ ./sortcat file|sort12123134232768989299*****

流程圖:

1』pipe()建立管道、fork()建立子進程

這裡,0-1-2分別表示標準輸入,標準輸出,標準錯誤。先建立管道,再由fork建立子進程,這裡子進程是完全繼承父進程的檔案描述符表。 『2』父進程和子進程分別執行dup2()

重新導向以後,父進程的標準輸入來自管道,子進程的標準輸出到管道。也就是將父進程的檔案描述符[3]處的指標拷貝到[0]對應的條目處;將子進程的檔案描述符4處的指標拷貝到[1]對應的條目處。 『3』各自調用close以後

調用close()關閉檔案描述符,相當於刪除檔案描述符表的對應條目。這裡, close(fd[0])和close(fd[1])的操作是不可以省略的:執行了2個 close以後,參見圖4, 只有子進程的ls
-l才會像管道寫資料,最終子進程終止,父進程會檢測到檔案結束;否則如果省略到close(),按照圖3所示,子進程終止以後,父進程的檔案描述符[4]仍然是為管道的寫操作開啟著,父進程將陷入無限期的阻塞,等待資料的寫入。

 注意: 關於這裡 在父、子進程中都需要 close() 兩次 有待驗證!

心得:

1

子進程的功能是讀出資訊,而父進程的功能是寫入資訊;因此在子進程那裡,要把管道的輸入端複製到標準輸出中,即dup2(fd[1],1)而父進程則要把管道寫端複製到標準輸入,即dup2(fd[0],0)。

 

2

dup()與dup2()的最大區別:

舉例說明:

                    close(1);         //關閉標準輸出

                    dup(fd[1]);     //把管道的輸入端複製到標準輸出

                    這兩個語句等價於:  dup2(fd[1],1);

所以dup2()是把close()和dup()這兩個函數整合在了同一個函數裡。這裡特別要注意的是:dup2()的兩個參數,是把前一個複製到後一個裡面,所以書上的例子中寫的是錯誤的。

3、還有就是exec()函數的用法,我一開始不知道“cat file“命令如何作為函數的參數,現在談談我的理解吧:

我的程式中execlp("cat","cat","file",NULL);第一個參數是為了指明該命令的路徑,第二個和第三個參數是該命令

所包含的所有參數,即把他們一一羅列出來。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.