IO Redirect 與 Pipe

  對於任何一個進程,在啓動時,都會打開三個流:stdin(標準輸入), stdout(標準輸出), stderr(標準錯誤輸出)。Stdout,stderr是process與Display之間,stdin是process與keyboard之間。也就是說系統的標準輸入輸出,是進程與設備間交流的橋樑。linux

  可是在不少狀況下,咱們的程序數據並不來自於標準輸入,咱們在使用標準輸出時,也不但願寫到顯示器上,多是文件,網絡,打印機等。這時候就須要IO Redirect來做用了。還有,爲了方便使用等,咱們但願將寫到Stdout的數據做爲另一個進程的輸入,其實這也是IO redirect的一種,不過它有個特殊的名字——pipe。網絡

 

         

 

一、IO Redirect

1.1 File handle (File Description)

       操做系統內核會爲每個進程分配不少file handler(也叫 File Description),其中初始時會分配3個handle,用數字0,1,2來表示,分別分配給了stdin, stdout, stderr。其餘的則是隨着須要分配的。app

       這樣一來,就能夠直接使用0,1,2來表示Stdio了。操作系統

 

在linux上使用lsof -p pid查看一個進程打開了哪些文件。下面是一個查看運行中的top命令的狀況:code

 

 

 

1.2 基本的重定向操做符:>與<

  < 將標準輸入(stdin, 0)重定向,也就是說數據來源不是鍵盤,而是其餘,例如文件等。blog

  > 將標準輸出(stdout, 1)重定向,也就是說數據再也不寫到顯示器,而是其餘地方。進程

  其中在 >,< 操做符的左邊,只能是FD,右邊多是file,也能夠是FD等。此外, <等價於 <1, >等價於1>,因此2> 就是將標準錯誤輸出(stderr, 2)重定向。ip

 

  IO redirect的本質是什麼呢?在我看來本質是FD的賦值。怎麼理解呢?pip

  默認狀況下一個,一個進程(例如:ls)是這樣的:io

 

對於一個進程而言:
#0 = keyboard
#1 = display
#2 = display

 

1.2.1 操做符右邊是文件

ls >a:表明了 fd1=a
#0 = keyboard
#1 = a
#2 = display

Ls 3>a :表明了fd3=a

sort<file.txt :表明了fd0=file.txt

 

1.2.2 操做符右邊是FD

若是但願在多個FD之間進行賦值運算,那麼就用>&或者<&。

那麼理解上仍是 >時賦值運算符,&則是dup2系統調用了。

2>&1的意思就是 對 FD1執行dup2,獲得FD1的拷貝,而後賦值給FD2,也就是說FD1指向了誰,FD2也去指向誰。

 

例如:

3>file.txt 2>&3 表明了:FD3-->file.txt,那麼FD2--->file.txt

須要注意的是:>自己不要求文件必須是存在的,可是通過了上述複製並賦值操做和後,啓動進程之初就要準備好相應的流,此時就須要文件file.txt必須是存在的。

 

 

1.3 變體操做符 >>

 

若是將stdout或者stderr 重定向到一個文件,但文件裏已經有內容,會是什麼結果呢?使用 > file時,文件中已有的內容會被truncate掉,也就是文件內容被清除了。

若是想要保留文件內容怎麼辦呢?

有一個變體操做符:>> 以append的方式重定向。

 

 

二、Pipe

       若是但願將輸出內容,直接做爲另一個程序的輸入,這種技術成爲Pipe,可以進行Pipe的進程,必須是父子進程。用「|」 來表示管道。Pipe也是進程間通訊的一種技術。

例如:lsof -p pid | grep xxx ,父進程是 lsof, 子進程是grep。

 

本篇內容適用於 Windows,Linux,Unix等操做系統。

相關文章
相關標籤/搜索