I/O重定向

Linux Shell 環境中支持輸入輸出重定向,用符號<和>來表示。0、1和2分別表示標準輸入、標準輸出和標準錯誤信息輸出,能夠用來指定須要重定向的標準輸 入或輸出,好比 2>a.txt 表示將錯誤信息輸出到文件a.txt中。javascript

同時,還能夠在這三個標準輸入輸出之間實現重定向,好比將錯誤信息重定向到標準輸出,能夠用 2>&1來實現java

Linux下還有一個特殊的文件/dev/null,它就像一個無底洞,全部重定向到它的信息都會消失得無影無蹤。這一點很是有用,當咱們不須要回 顯程序的全部信息時,就能夠將輸出重定向到/dev/null。git

若是想要正常輸出和錯誤信息都不顯示,則要把標準輸出和標準錯誤都重定向到/dev/null, 例如:shell

# ls 1>/dev/null 2>/dev/nullsocket

還有一種作法是將錯誤重定向到標準輸出,而後再重定向到 /dev/null,例如:tcp

# ls >/dev/null 2>&1this

注意:此處的順序不能更改,不然達不到想要的效果,此時先將標準輸出重定向到 /dev/null,而後將標準錯誤重定向到標準輸出,因爲標準輸出已經重定向到了/dev/null,所以標準錯誤也會重定向到/dev/null,於 是一切靜悄悄spa

 

 

 

____________________________________________________________code

用過Unix的恐怕沒有不知道I/O重定向的,ls>a.txt就是一個I/O重定向。所謂I/O重定向,簡單的理解就是透明的改變命令預約 的輸入源或輸出目的地,像ls>a.txt就是把輸出目的地改爲了a.txt而不是預約的stdout.blog

 

要想理解好I/O重定向,就不能不對Unix的文件描述符(File Descriptor)有所瞭解。文件描述符的概念和在C語言裏的操做,這裏再也不贅述了,資料不少。此處只說說Shell裏的重定向。

 

輸出重定向

 

格式[n]>word

Shell先對word進行各類擴展(花括號、波浪號、變量擴展等,詳見Shell命令中的擴展和替換 ),將最後擴展的結果做爲一個文件。Shell打開這個文件並在內部將新獲得的文件描述符複製到n。n若是省略則默認爲1

>和>>的區別在於,使用前者,Shell會建立新文件,若是文件已經存在,原來的內容會被清空後者要文件必須存在,在文件後 面添加內容

 

輸入重定向

  格式[n]<word

Shell先對word進行各類擴展(花括號、波浪號、變量擴展等,詳見Shell命令中的擴展和替換 ),將最後擴展的結果做爲一個文件。Shell打開這個文件並在內部將新獲得的文件描述符複製到n。n若是省略則默認爲0,也就是標準輸入。

 

同時重定向標準錯誤和標準輸出

格式:&>word或>&word,推薦第一種。shell支持對word的擴展,且word擴展後做爲一個文件名。 至關於:
>word 2>&1

Here Documen t: 把下面一段代碼重定向到命令的標準輸入。
格式 <<[-] word
        here-document
    delimiter

delimiter是一個結束指示器,至關於咱們在控制檯輸入的ctrl+D。
Shell不對word進行任何擴展。

Shell代碼
  1. [jjz@localhost test]$ abc=hello  
  2. [jjz@localhost test]$ cat <<$abc  
  3. > this is here document  
  4. > hello            這 裏並未中止,shell不對$abc進行擴展,結束符是$abc而不是hello  
  5. > $abc  
  6. this is here document  
  7. hello  
 

若是word是引號括起來的,delimiter爲word去除全部的引號後字符串,不對here-document進行擴展。

Shell代碼
  1. [jjz@localhost test]$ cat << "DONE"  
  2. > $abc  
  3. DONE  
  4. $abc    DONE 兩邊有引號,所以沒有對abc進行擴展  
 

若是word沒有引號,對here-document進行擴展。

Shell代碼
  1. [jjz@localhost test]$ cat << DONE  
  2. > $abc  
  3. > DONE  
  4. hello    對 abc進行了擴展  
 

若是寫了-,則輸出是全部的引導tab都去除.

還有一種<<<word,對word擴展並做爲命令的標準輸入

 

複製文件描述符
輸入:格式 [n]<&word。

這個功能和直接在c裏面調用dup2()差很少,很好很強大。

word擴展以後應該獲得一個數字。shell獲得word所指定的輸入描述符的一個copy,並設定爲n。若是word所制定的數字不是一個有效 地輸入描述符,會出錯。若是word獲得的結果是 -,則輸入被關閉。n默認爲0.複製輸出描述符也是這樣的。

輸出:格式 [n]>&word。

和上面差很少,只不過這個是複製輸出描述符。

word擴展以後應該獲得一個數字。shell獲得word所指定的輸入描述符的一個copy,並設定爲n。若是word所制定的數字不是一個有效 地輸出描述符,會出錯。若是word獲得的結果是 -,則輸入被關閉。n默認爲0.複製輸出描述符也是這樣的。


移動輸出描述符
輸入:形式 [n]<&digit-

移動文件描述符digit到n。支持對digit的擴展。

基本上就是先copy到n再關閉digit。

輸出:形式 [n]>&digit-

和上面類似,不過是針對輸出的

 

注: 雖然上面說複製和移動文件描述符是要注意輸入和輸出的區別,不過根據個人嘗試,複製和移動文件描述符時,shell不會判斷文件描述符是輸入仍是輸出(因 爲dup2不判斷……),因此照樣能夠用1(標準輸出)<&x,把輸出的文件描述符x複製到1,不是隻能使用1>&x

 

其餘

  1. 爲讀寫打開: [n]<>word.
  2. 重定向處理順序:左到右。
    有的時候要注意重定向的順序,不然可能會不正確
  3. exec 可使用指定的描述符打開一個文件(能夠配合複製、移動文件描述符使用)
    exec 0<test.txt   以只讀方式打開文件test.txt,使用文件描述符0
    exec 1>test.txt   以只寫方式打開文件test.txt,使用文件描述符1,這樣後面的命令的輸出所有到了test.txt裏
    exec 1<&-           關閉文件描述符1,這樣後面命令的輸出全沒了

  4. 幾個特殊的文件名
    • /dev/fd/n,n是一個有效正整數,引用文件描述符n。
    • /dev/stdin
    • /dev/stdout
    • /dev/stderr
    • /dev/tcp/host/port 打開並進行socket傳輸
    • /dev/udp/host/port 打開並進行socket傳輸
相關文章
相關標籤/搜索