特殊文件——管道

管道與重定向


概述

對於一些須要進程間的協做來解決問題的場景,進程間的通訊是必要的。而最簡單的UNIX進程通訊機制就是管道,他是由特殊文件表示的。調用者能夠經過文件描述符fd[0]和fd[1]來訪問它,從fd[1]寫入的數據能夠按照先進先出的順序從fd[0]中讀出。html

文件描述符:在形式上是一個非負整數。實際上,它是一個索引值,指向內核爲每個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者建立一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫每每會圍繞着文件描述符展開。可是文件描述符這一律念每每只適用於UNIX、Linux這樣的操做系統。shell

咱們要明白,每一個Unix進程(除了可能的守護進程)應均有三個標準的POSIX文件描述符,對應於三個標準流:vim

整數值 名稱 <unistd.h>符號常量 <stdio.h>文件流
0 Standard input STDIN_FILENO stdin
1 Standard output STDOUT_FILENO stdout
2 Standard error STDERR_FILENO stderr

例如:$ls -l | head -5中,|就表示一個管道,ls的標準輸出被經過中間通訊緩衝區被「鏈接」到了head的標準輸入中。 此命令執行過程的文件描述符表的狀態函數

實現重定向

瞭解了文件描述符的概念後,咱們就能利用dup2函數來實現重定向。下面咱們來用c語言模擬$ls -l | head -5spa

源代碼

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    pid_t child;
    int fd[2];

    if ((pipe(fd) == -1) || ((child = fork()) == -1)) {
        perror("Failed to fork.");
        return 1;
    }

    if (child == 0) {     /* 子進程 */ 
        if (dup2(fd[1], STDOUT_FILENO) == -1)
            perror("Failed to redirect stdout of ls");
        else if ((close(fd[0]) == -1) || (close(fd[1]) == -1))
            perror("Failed to close extra pipe descriptors on ls");
        else {
            execl("/bin/ls", "ls", "-l", NULL);
            perror("Failed to execute ls");
        }
    }

    /* 父進程 */ 
    if (dup2(fd[0], STDIN_FILENO) == -1)
        perror("Failed to redirect stdin of head");
    else if ((close(fd[0]) == -1) || (close(fd[1]) == -1))
        perror("Failed to close extra pipe descriptors on head");
    else {
        execl("/usr/bin/head", "head", "-5", NULL);
        perror("Failed to execute head");
    }
    return 0;
}

過程圖示

fork函數在建立一個子進程時,子進程就會繼承父進程的環境和上下文中的大部份內容的一份拷貝,包括信號狀態調度參數文件描述符表。因爲子進程在被建立時會收到父進程文件描述符表的一份拷貝,所以對於在建立子進程前就打開的文件來書,父進程和子進程將共享同一個文件的偏移量。 調用fork後,文件描述符表狀態以下: 調用後的文件描述符表狀態操作系統

兩個dup2函數執行完畢後,文件描述符表的狀態以下: 兩個函數執行完畢後的文件描述符表狀態設計

調用close完畢後,文件描述符表的狀態以下: 兩個函數執行完畢後的文件描述符表狀態3d

編譯運行

$ gcc redirect_demo.c
$ ./a.out
total 4888
-rwxrwxr-x  1 chris chris    8576 3月   5 21:23 a.out
drwxrwx--- 10 chris chris    4096 3月   5 21:23 ccls
-rw-rw-r--  1 chris chris     637 3月   5 21:23 coc-25627.vim
-rw-rw-r--  1 chris chris   25829 3月   5 15:06 coc-ultisnips-c7dd5acb3d1574c377e86b60ee637c3c.py

原文出處:https://www.cnblogs.com/chrisynl/p/12422837.htmlcode

相關文章
相關標籤/搜索