在瞭解重定向以前,咱們先來看看linux 的文件描述符。
linux文件描述符:能夠理解爲linux跟蹤打開文件,而分配的一個數字,這個數字有點相似c語言操做文件時候的句柄,經過句柄就能夠實現文件的讀寫操做。 用戶能夠自定義文件描述符範圍是:3-num,這個最大數字,跟用戶的:ulimit –n 定義數字有關係,不能超過最大值。
linux啓動後,會默認打開3個文件描述符,分別是:標準輸入standard input 0,正確輸出standard output 1,錯誤輸出:error output 2
之後打開文件後。新增文件綁定描述符 能夠依次增長。 一條shell命令執行,都會繼承父進程的文件描述符。所以,全部運行的shell命令,都會有默認3個文件描述符。
對於任何一條linux 命令執行,它會是這樣一個過程:
一個命令執行了:
先有一個輸入:輸入能夠從鍵盤,也能夠從文件獲得
命令執行完成:成功了,會把成功結果輸出到屏幕:standard output默認是屏幕
命令執行有錯誤:會把錯誤也輸出到屏幕上面:standard error默認也是指的屏幕
文件輸入輸出由追蹤爲一個給定的進程全部打開文件的整數句柄來完成。這些數字值就是文件描述符。最爲人們所知的文件米描述符是 stdin, stdout 和 stderr,文件描述符的數字分別是0,1和2。這些數字和各自的設備是保留的。一個命令執行前,先會準備好全部輸入輸出,默認分別綁定(stdin,stdout,stderr),若是這個時候出現錯誤,命令將終止,不會執行。命令解析過程,能夠參考:Linux Shell 通配符、元字符、轉義符使用實例介紹
這些默認的輸出,輸入都是linux系統內定的,咱們在使用過程當中,有時候並不但願執行結果輸出到屏幕。我想輸出到文件或其它設備。這個時候咱們就須要進行輸出重定向了。
linux shell下經常使用輸入輸出操做符是:
1. 標準輸入 (stdin) :代碼爲 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0 0表明:/dev/stdin 2. 標準輸出 (stdout):代碼爲 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1 1表明:/dev/stdout 3. 標準錯誤輸出(stderr):代碼爲 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2表明:/dev/stderr
[cpp] view plain copy
- command-line1 [1-n] > file或文件操做符或設備
-
- 上面命令意思是:將一條命令執行結果(標準輸出,或者錯誤輸出,原本都要打印到屏幕上面的) 重定向其它輸出設備(文件,打開文件操做符,或打印機等等)1,2分別是標準輸出,錯誤輸出。
-
- 實例:
- #顯示當前目錄文件 test.sh test1.sh test1.sh實際不存在
- [chengmo@centos5 shell]$ ls test.sh test1.sh
- ls: test1.sh: 沒有這個文件和目錄
- test.sh
-
- #正確輸出與錯誤輸出都顯示在屏幕了,如今須要把正確輸出寫入suc.txt
- # 1>能夠省略,不寫,默認所至標準輸出
- [chengmo@centos5 shell]$ ls test.sh test1.sh 1>suc.txt
- ls: test1.sh: 沒有這個文件和目錄
- [chengmo@centos5 shell]$ cat suc.txt
- test.sh
-
- #把錯誤輸出,不輸出到屏幕,輸出到err.txt
- [chengmo@centos5 shell]$ ls test.sh test1.sh 1>suc.txt 2>err.txt
- [chengmo@centos5 shell]$ cat suc.txt err.txt
- test.sh
- ls: test1.sh: 沒有這個文件和目錄
- #繼續追加把輸出寫入suc.txt err.txt 「>>」追加操做符
- [chengmo@centos5 shell]$ ls test.sh test1.sh 1>>suc.txt 2>>err.txt
-
- #將錯誤輸出信息關閉掉
- [chengmo@centos5 shell]$ ls test.sh test1.sh 2>&-
- test.sh
- [chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null
- test.sh
- #&[n] 表明是已經存在的文件描述符,&1 表明輸出 &2表明錯誤輸出 &-表明關閉與它綁定的描述符
- #/dev/null 這個設備,是linux 中黑洞設備,什麼信息只要輸出給這個設備,都會給吃掉
-
- #關閉全部輸出
- [chengmo@centos5 shell]$ ls test.sh test1.sh 1>&- 2>&-
- #關閉 1 ,2 文件描述符
- [chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null 1>/dev/null
- #將1,2 輸出轉發給/dev/null設備
- [chengmo@centos5 shell]$ ls test.sh test1.sh >/dev/null 2>&1
- #將錯誤輸出2 綁定給 正確輸出 1,而後將 正確輸出 發送給 /dev/null設備 這種經常使用
- <p>[chengmo@centos5 shell]$ ls test.sh test1.sh &>/dev/null
- #& 表明標準輸出 ,錯誤輸出 將全部標準輸出與錯誤輸出 輸入到/dev/null文件
注意:
一、shell遇到」>」操做符,會判斷右邊文件是否存在,若是存在就先刪除,而且建立新文件。不存在直接建立。不管左邊命令執行是否成功。右邊文件都會變爲空。
二、「>>」操做符,判斷右邊文件,若是不存在,先建立。以添加方式打開文件,會分配一個文件描述符[不特別指定,默認爲1,2]而後,與左邊的標準輸出(1)或錯誤輸出(2) 綁定。
三、當命令:執行完,綁定文件的描述符也自動失效。0,1,2又會空閒。
四、一條命令啓動,命令的輸入,正確輸出,錯誤輸出,默認分別綁定0,1,2文件描述符。
五、一條命令在執行前,先會檢查輸出是否正確,若是輸出設備錯誤,將不會進行命令執行
[cpp] view plain copy
- 格式:
-
- command-line [n] <file或文件描述符&設備
-
- 將然有,命令默認從鍵盤得到的輸入,改爲從文件,或者其它打開文件以及設備輸入。執行這個命令,將標準輸入0,與文件或設備綁定。將由它進行輸入。
-
- 實例:
-
-
- [chengmo@centos5 shell]# cat > catfile
- testing
- cat file test
- #這裏按下 [ctrl]+d 離開
- #從標準輸入【鍵盤】得到數據,而後輸出給catfile文件
-
- [chengmo@centos5 shell]$ cat>catfile <test.sh
- #cat 從test.sh 得到輸入數據,而後輸出給文件catfile
-
-
- [chengmo@centos5 shell]$ cat>catfile <<eof
- test a file
- test!
- eof
-
- #<< 這個連續兩個小符號, 他表明的是『結束的輸入字符』的意思。這樣當空行輸入eof字符,輸入自動結束,不用ctrl+D
[cpp] view plain copy
- 格式:
-
- exec 文件描述符[n] <或> file或文件描述符或設備
-
- 在上面講的輸入,輸出重定向 將輸入,輸出綁定文件或設備後。只對當前那條指令是有效的。若是須要在綁定以後,接下來的全部命令都支持的話。就須要用exec命令
-
- 實例:
-
-
- [chengmo@centos5 shell]$ exec 6>&1
- #將標準輸出與fd 6綁定
-
- [chengmo@centos5 shell]$ ls /proc/self/fd/
- 0 1 2 3 6
- #出現文件描述符6
-
- [chengmo@centos5 shell]$ exec 1>suc.txt
- #將接下來全部命令標準輸出,綁定到suc.txt文件(輸出到該文件)
-
- [chengmo@centos5 shell]$ ls -al
- #執行命令,發現什麼都不返回了,由於標準輸出已經輸出到suc.txt文件了
-
- [chengmo@centos5 shell]$ exec 1>&6
- #恢復標準輸出
-
-
- [chengmo@centos5 shell]$ exec 6>&-
- #關閉fd 6描述符
-
- [chengmo@centos5 ~]$ ls /proc/self/fd/
- 0 1 2 3
- 說明:使用前先將標準輸入保存到文件描述符6,這裏說明下,文件描述符默認會打開0,1,2 還可使用自定義描述符 。而後對標準輸出綁定到文件,接下來全部輸出都會發生到文件。 使用完後,恢復標準的輸出,關閉打開文件描述符6。
-
- 有趣事情:
-
- 可能有朋友會這樣用:exec 1>suc.txt ,接下來全部輸出都綁定到suc.txt 文件,那麼怎麼樣恢復原來的呢? 試試你就會發現問題所在……
[cpp] view plain copy
- exec 3<>test.sh;
- #打開test.sh可讀寫操做,與文件描述符3綁定
-
- while read line<&3
- do
- echo $line;
- done
- #循環讀取文件描述符3(讀取的是test.sh內容)
- exec 3>&-
- exec 3<&-
- #關閉文件的,輸入,輸出綁定
[cpp] view plain copy
- 學習就要總結,總結才能夠提升了。哈哈!
-
- 估計還有一些朋友是頭暈暈的。怎麼linux的重定向這麼複雜呢,又是文件打開描述符又是讀,還有些,還有默認標準輸入輸出。
-
- 其實,總結一下,重定向應用一般就如下兩點:
-
- 一、從新設置命令的默認輸入,輸出,指向到本身文件(文件,文件描述符,設備其實都是文件,由於linux就是基於設備也是文件,描述符也指向是文件,哈哈)
-
- 二、擴展本身新的描述符,對文件進行讀寫操做
參考資料:http://www.makeru.com.cn/ 嵌入式學習交流羣:201030910 |