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進行任何擴展。
- [jjz@localhost test]$ abc=hello
- [jjz@localhost test]$ cat <<$abc
- > this is here document
- > hello 這 裏並未中止,shell不對$abc進行擴展,結束符是$abc而不是hello
- > $abc
- this is here document
- hello
[jjz@localhost test]$ abc=hello
[jjz@localhost test]$ cat <<$abc
> this is here document
> hello 這裏並未中止,shell不對$abc進行擴展,結束符是$abc而不是hello
> $abc
this is here document
hello
若是word是引號括起來的,delimiter爲word去除全部的引號後字符串,不對here-document進行擴展。
- [jjz@localhost test]$ cat << "DONE"
- > $abc
- > DONE
- $abc DONE 兩邊有引號,所以沒有對abc進行擴展
[jjz@localhost test]$ cat << "DONE"
> $abc
> DONE
$abc DONE兩邊有引號,所以沒有對abc進行擴展
若是word沒有引號,對here-document進行擴展。
- [jjz@localhost test]$ cat << DONE
- > $abc
- > DONE
- hello 對 abc進行了擴展
[jjz@localhost test]$ cat << DONE
> $abc
> DONE
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
其餘
- 爲讀寫打開: [n]<>word.
- 重定向處理順序:左到右。
有的時候要注意重定向的順序,不然可能會不正確。
- exec 可使用指定的描述符打開一個文件(能夠配合複製、移動文件描述符使用)
exec 0<test.txt 以只讀方式打開文件test.txt,使用文件描述符0
exec 1>test.txt 以只寫方式打開文件test.txt,使用文件描述符1,這樣後面的命令的輸出所有到了test.txt裏
exec 1<&- 關閉文件描述符1,這樣後面命令的輸出全沒了。
- 幾個特殊的文件名
- /dev/fd/n,n是一個有效正整數,引用文件描述符n。
- /dev/stdin
- /dev/stdout
- /dev/stderr
- /dev/tcp/host/port 打開並進行socket傳輸
- /dev/udp/host/port 打開並進行socket傳輸