引子:在linux系統的終端上輸入ps aux | grep bash
,會在終端上輸出:
lapvir@ubuntu:~$ ps aux | grep bash
lapvir 3330 0.0 0.2 29568 5060 pts/0 ss+ 15:47 0:00 /bin/bash
lapvir 3507 0.0 0.2 29476 4988 pts/4 ss 15:58 0:00 bash
lapvir 5482 0.0 0.0 21292 968 pts/4 s+ 19:48 0:00 grep --color=auto bash
這裡的|
就是管道的意思,ps aux
將資料寫入到終端上,grep bash
從終端上讀取並搜尋出含有bash
的程序。下面我將剖析一下這背後的過程。
linux系統中預設了前三個檔案識別符號,指向dev/tty
這個檔案,如下圖所示:
而我將ps aux | grep bash
理解為下圖所示的過程。
接下來我將要實現的功能是父程序通過管道寫入ps aux
,子程序通過管道讀取資料並搜尋出含有bash
的程序。為了實現這個功能需要將輸入輸出的檔案識別符號從終端指向管道的兩端,這自然就引出了dup2()
函式。下面是是這個過程的示意圖:
dup2函式的函式原型為:
#include int dup2(int oldfd, int newfd);
這個函式的功能是讓檔案識別符號newfd指向檔案識別符號oldfd所指向的檔案。
舉例:
int fd = open("temp", o_creat | o_rdwr, 0664);
dup2(fd, stdout_fileno);
close(fd);
我們開啟了乙個叫temp的新檔案,並建立乙個檔案描述符fd指向temp,我們呼叫dup2函式,這會讓我們用fd這個檔案描述符替換掉stdout_fileno這個檔案描述符所指向的位置,這樣原本任何從終端寫出的東西,都會寫到fd這個檔案描述符所指向的檔案中,即temp。需要注意的是,dup2函式在將fd複製到stdout_fileno後,就會將fd給關閉。理解了dep2這個函式,接下來的就容易理解了。
下面我將結合**來具體講解這乙個過程。
#include #include #include #include #include #include int main(int argc, const char* ar**)
pid_t pid = fork();//建立子程序,這樣子程序也有兩個檔案描述符,讀端和寫端
if(pid == -1)
if(pid>0)else if(pid == 0)
printf("pipe[0] = %d\n", fd[0]);
printf("pipe[1] = %d\n", fd[1]);
close(fd[0]);
close(fd[1]);
return 0;
}
關於stdout是寫入,stdin是讀取,這乙個地方我感覺是挺難理解的,我得想法是這樣的:
站在終端的角度上,stdout把東西寫到終端上,stdin是終端讀取東西。
例如在終端上輸入ps aux
,通過檔案描述符stdout_fileno
把資料直接寫到當前終端上。
linux下程式設計 作業系統 管道通訊
1 有名管道 乙個可以在檔案系統中長期存在的 具有路徑名的檔案。用系統呼叫mknod 建立。它克服無名管道使用上的侷限性,可讓更多的程序也能利用管道進行通訊。因而其它程序可以知道它的存在,並能利用路徑名來訪問該檔案。對有名管道的訪問方式與訪問其他檔案一樣,需先用open 開啟。2 無名管道 乙個臨時...
linux系統管道命令學習
管道是一種兩個程序間進行單向通訊的機制。因為管道傳遞資料的單向性,管道又稱為半雙工管道。管道的這一特點決定了器使用的侷限性。管道是linux支援的最初unix ipc形式之一,具有以下特點 資料只能由乙個程序流向另乙個程序 其中乙個讀管道,乙個寫管道 如果要進行雙工通訊,需要建 立兩個管道。管道只能...
Linux 程序間通訊 管道通訊
管道是 單向的 先進先出的,它把乙個程序的輸出和另乙個程序的輸入連線在一起,乙個程序 寫程序 在管道的尾部寫入資料,另乙個程序 讀程序 從管道的頭部讀出資料 資料被乙個程序讀出之後,將被從管道中刪除,其它讀程序將不能再讀到這些資料,管道提供了 簡單的流控制機制,程序試圖讀空管道時,程序將阻塞,同樣,...