Shell的管道符號的原理是什么?

不管是大家熟悉的bash還是好用的zsh,從Unix遠古時代開始shell就伴隨著我們程序員左右,我們可以執(zhí)行一個命令如ls,cd,cat test.txt,也可以讓一組命令通過管道符連接起來完成更高級的工作,比如說我們搜尋test.txt中包含"hello world"字符串的行我們可以用下面的命令:cat test.txt | grep "hello world".那么這么好用的管道符號的背后是如何實現(xiàn)的呢?下面我就用一個簡單的示例來說明一下.
我們的測試文件的格式如下:

//test.txt
this is line 1 ,data
this is line 2 ,data
this is line 3 ,data
this is line 4 ,data
this is line 5 ,data
this is line 6 ,data
this is line 7 ,data
this is line 8 ,data
this is line 9 ,data
this is line 10 ,data
...(共有100行)...

我們寫個簡單的小程序來說明一下管道符的內在原理:
下面的例子模擬在shell中執(zhí)行cat test.txt|grep 96,為了看起來簡潔明了一些錯誤處理就沒寫了.

/*探索shell如何在兩個命令之間建立管道*/
/*過程是先exec p1,然后exec p2,將其用管道聯(lián)系在一起*/
/*注意只有所有的寫端文件描述符都關閉才會使得read讀到EOF*/
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
int main(){
    pid_t pid_p1,pid_p2;
    int pipe_fds[2];
    if(pipe(pipe_fds) != 0)
    {
       exit(1);
    }
    if((pid_p2 = fork()) == 0)// 子進程1
    {
        dup2(pipe_fds[0],STDIN_FILENO);// 將標準輸入重定向到管道的讀取端
        close(pipe_fds[0]);
        close(pipe_fds[1]); // 一定要關閉,因為已經(jīng)dup過了,否則read的時候不會知道是否已經(jīng)讀完
        execlp("grep","grep","96",(char*)0);
    }
    else if(pid_p2 < 0)
    {
        exit(1);// 生成進程失敗
    }

    if((pid_p1 = fork()) == 0) // 子進程2
    {
        dup2(pipe_fds[1],STDOUT_FILENO);//將標準輸出重定向到管道寫入端 
        close(pipe_fds[0]);
        close(pipe_fds[1]); // 一定要關閉,因為已經(jīng)dup過了,否則read的時候不會知道是否已經(jīng)讀完
        execlp("cat","cat","test.txt",(char*)0); // exec "cat test.txt"
    }
    else if(pid_p1 < 0)
    {
        exit(1);// 生成進程失敗
    }

    // 主進程
    close(pipe_fds[0]);
    close(pipe_fds[1]); // 一定要關閉,主進程不需要管道
    while(wait(NULL)>0); // wait for all processes.
    return 0;
}

最主要的調用就是pip()dup2()了,主要解釋下dup2()的目的在于重定向標準輸入輸出,其他的部分代碼注釋也解釋的比較清楚,就不贅述了,更多參考資料請見<Unix環(huán)境高級編程>的io章節(jié),文件章節(jié),進程部分乃至偽終端部分.

如果從頭說來那就是shell解析用戶敲入的命令,明白用戶要啟動cat 程序和grep程序,并且將cat程序的標準輸出通過pipe管道重定向到grep的標準輸入之中,shell解析出用戶的意圖之后,會調用類似上面的例程,從而將這個命令組合執(zhí)行完畢.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容