從定義上來看,Linux重定向就是指修改原來默認的一些東西,對原來系統命令的默認執行方式進行改變,好比說簡單的我不想看到在顯示器的輸出而是但願輸出到某一文件中就能夠經過Linux重定向來進行這項工做。在進一步探索重定向以前,咱們先理解一下linux文件描述符。html
文件描述符理解爲linux跟蹤打開文件,而分配的一個數字,這個數字有點相似c語言操做文件時候的句柄,經過句柄就能夠實現文件的讀寫操做。 用戶能夠自定義文件描述符範圍是:3-num,這個最大數字,跟用戶的:ulimit –n 定義數字有關係,不能超過最大值。java
linux啓動後,會默認打開3個文件描述符,分別是:標準輸入standard input 0,正確輸出standard output 1,錯誤輸出:error output 2,每一個文件有對應的文件描述符來方便咱們使用:linux
類型 | 文件描述符 | 默認狀況 | 對應文件句柄位置 |
---|---|---|---|
標準輸入(standard input) | 0 | 從鍵盤得到輸入 | /proc/self/fd/0 |
標準輸出(standard output) | 1 | 輸出到屏幕(即控制檯) | /proc/self/fd/1 |
錯誤輸出(error output) | 2 | 輸出到屏幕(即控制檯) | /proc/self/fd/2 |
一般,一個命令執行過程以下:shell
先有一個輸入:輸入能夠從鍵盤,也能夠從文件獲得;centos
命令執行完成:成功了,會把成功結果輸出到屏幕:standard output默認是屏幕;bash
命令執行有錯誤:會把錯誤也輸出到屏幕上面:standard error默認也是指的屏幕;post
因此咱們平時在執行shell命令中,都默認是從鍵盤得到輸入,而且將結果輸出到控制檯上。可是咱們能夠經過更改文件描述符默認的指向,從而實現輸入輸出的重定向。好比咱們將1指向文件,那麼標準的輸出就會輸出到文件中。接下來咱們進一步的介紹Linux中的輸入重定向和輸出重定向。this
輸出重定向的使用方式很簡單,基本的一些命令格式以下:url
命令 | 介紹 |
---|---|
command >file | 把標準輸出(stdout)重定向到 file 文件中; |
command 1>file | 同上; |
command >>file | 把 stdout 重定向到 file 文件中(追加); |
command 1>>file | 同上; |
command 2>file | 把標準錯誤(stderr)重定向到 file 文件中; |
command 2>>file | 把 stderr重定向到 file 文件中(追加); |
command >> file 2>&1 | 把 stdout 和 stderr 一塊兒重定向到 file 文件中(追加); |
cmd > file 2>&1 | 把 stdout 和 stderr 一塊兒重定向到 file 文件中; |
cmd >> file 2>&1 | 把 stdout 和 stderr 一塊兒重定向到 file 文件中(追加); |
咱們使用>
或者>>
對輸出進行重定向。符號的左邊表示文件描述符,若是沒有的話表示1,也就是標準輸出,符號的右邊能夠是一個文件,也能夠是一個輸出設備。當使用>
時,會判斷右邊的文件存不存在,若是存在的話就先刪除,而後建立一個新的文件,不存在的話則直接建立。可是當使用>>
進行追加時,則不會刪除原來已經存在的文件。spa
格式:
command-line1 [1-n] > file或文件操做符或設備
這條命令意思是:將一條命令執行結果(標準輸出,或者錯誤輸出,原本都要打印到屏幕上面的) 重定向其它輸出設備(文件,打開文件操做符,或打印機等等)1,2分別是標準輸出,錯誤輸出。
實例:
#查看文件內容,1.txt 2.txt (其中2.txt文件不存在) [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt this is a.txt cat: 2.txt: No such file or directory #標準輸出與錯誤輸出都顯示在屏幕了, #如今須要把標準輸出寫入到1.log中 # 1>能夠省略,表示標準輸出 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>1.log cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt >1.log cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]#cat 1.log this is a.txt #標準輸出不輸出到屏幕,輸出到1.log中 #錯誤輸出不輸出到屏幕,輸出到2.log中 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>1.log 2>2.log [root@sccprocddev02:/home/upro01]#cat 1.log 2.log this is a.txt cat: 2.txt: No such file or directory #將標準輸出和錯誤輸出分別追加到文件1.log和2.log中 「>>」追加操做符 #能夠看到兩個文件分別多出一行輸出的內容 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>>1.log 2>>2.log [root@sccprocddev02:/home/upro01]#cat 1.log 2.log this is a.txt this is a.txt cat: 2.txt: No such file or directory cat: 2.txt: No such file or directory [root@sccprocddev02:/home/upro01]# 高級用法 #將錯誤輸出信息關閉掉,控制檯只打印了標準輸出 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 2>&- this is a.txt [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 2>/dev/null this is a.txt #&[n] 表明是已經存在的文件描述符,&1 表明輸出 &2表明錯誤輸出&-表明關閉與它綁定的描述符 #/dev/null 這個設備,是linux 中黑洞設備,什麼信息只要輸出給這個設備,都會給吃掉 #關閉全部輸出 #關閉 1 ,2 文件描述符 [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt 1>&- 2>&- #將1,2 輸出轉發給/dev/null設備 [chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null 1>/dev/null [root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt >/dev/null 2>&1 #將錯誤輸出2綁定給正確輸出1,而後將正確輸出發送給 /dev/null設備 這種經常使用
#文件描述符前必須有個 &, 不然2>1就變成將錯誤輸出輸出到一個名爲1的文件了
[root@sccprocddev02:/home/upro01]#cat 1.txt 2.txt &>/dev/null #& 表明全部文件描述符,該命令會將全部標準輸出與錯誤輸出輸入到/dev/null文件
在理解了輸出重定向以後,理解輸入重定向就會容易得多。對輸入重定向的基本命令以下:
命令 | 介紹 |
---|---|
command <filename | 以filename文件做爲標準輸入 |
command 0<filename | 同上 |
command <<delimiter | 從標準輸入中讀入,直到遇到delimiter分隔符 |
command < file >file2 | command命令以 file 文件做爲標準輸入(stdin),以 file2文件做爲stdout; |
cat <>file | 以讀寫的方式打開 file; |
咱們使用<
對輸入作重定向,若是符號左邊沒有寫值,那麼默認就是0。
格式:
command-line [n] <file或文件描述符&設備
命令默認從鍵盤得到的輸入,使用輸入重定向改爲從文件,或者其它打開文件以及設備輸入。執行這個命令,將標準輸入0,與文件或設備綁定。將由它進行輸入。
實例:
[root@sccprocddev02:/home/upro01]#cat > stdout.txt this is stdout.txt ^C [root@sccprocddev02:/home/upro01]#cat stdout.txt this is stdout.txt #這裏使用ctrl+d 或者ctrl+c退出輸入 #從標準輸入[鍵盤]得到數據,而後輸出給stdout.txt文件 [root@sccprocddev02:/home/upro01]#cat > stdout2.txt < stdout.txt [root@sccprocddev02:/home/upro01]#cat stdout2.txt this is stdout.txt #從stdout.txt得到輸入數據,而後輸出給文件catfile [root@sccprocddev02:/home/upro01]#cat > stdout3.txt << end > first line > second line > end [root@sccprocddev02:/home/upro01]#cat stdout3.txt first line second line #<< 這個連續兩個小符號, 他表明的是[結束的輸入字符]的意思。這樣當空行輸入end字符時,自動退出輸入,不須要使用ctrl+d或者ctrl+c退出
前面的例子中咱們執行過以下一條命令
cat 1.txt 2.txt >/dev/null 2>&1
這條命令其實分爲兩命令,一個是>/dev/null
,另外一個是2>&1
。
>/dev/null
這條命令的做用是將標準輸出1重定向到/dev/null中。/dev/null表明linux的空設備文件,全部往這個文件裏面寫入的內容都會丟失,俗稱「黑洞」。那麼執行了>/dev/null
以後,標準輸出就會再也不存在,沒有任何地方可以找到輸出的內容。
2>&1
這條命令用到了重定向綁定,採用&能夠將兩個輸出綁定在一塊兒。這條命令的做用是錯誤輸出將和標準輸出同用一個文件描述符,說人話就是錯誤輸出將會和標準輸出輸出到同一個地方。
linux在執行shell命令以前,就會肯定好全部的輸入輸出位置,而且從左到右依次執行重定向的命令,因此>/dev/null 2>&1
的做用就是讓標準輸出重定向到/dev/null中(丟棄標準輸出),而後錯誤輸出因爲重用了標準輸出的描述符,因此錯誤輸出也被定向到了/dev/null中,錯誤輸出一樣也被丟棄了。執行了這條命令以後,該條shell命令將不會輸出任何信息到控制檯,也不會有任何信息輸出到文件中。
注意:這裏的>/dev/null 和 2>&1的順序是不能寫反的,2>&1 >/dev/null這樣的寫法結果將是:標準錯誤打印到屏幕,而標準輸出不打印到屏幕。
咱們用一個表格來更好地說明這兩條命令的區別:
命令 | 標準輸出 | 錯誤輸出 |
---|---|---|
>/dev/null 2>&1 | 丟棄 | 丟棄 |
2>&1 >/dev/null | 丟棄 | 屏幕 |
在工做中咱們經常會使用到重定向功能,好比在啓動java項目時,由於咱們已經配置好了日誌文件,因此咱們不想輸出默認的nohup.out日誌,那麼咱們一般會使用以下命令
# nohup java -jar xxxx.jar >/dev/null 2>&1 &
格式:
exec 文件描述符[n] <或> file或文件描述符或設備
在上面講的輸入,輸出重定向 將輸入,輸出綁定文件或設備後。只對當前那條指令是有效的。若是須要在綁定以後,接下來的全部命令都支持的話。就須要用exec命令
[root@sccprocddev02:/home/upro01]$ exec 6>&1 #將標準輸出與fd 6綁定 [root@sccprocddev02:/home/upro01]$ ls /proc/self/fd/ 0 1 2 3 6 #出現文件描述符6 [root@sccprocddev02:/home/upro01]$ exec 1>6.txt #將接下來全部命令標準輸出,綁定到6.txt文件(輸出到該文件) [root@sccprocddev02:/home/upro01]$ ls -al #執行命令,發現什麼都不返回了,由於標準輸出已經輸出到6.txt文件了 [root@sccprocddev02:/home/upro01]$ exec 1>&6 #恢復標準輸出 [root@sccprocddev02:/home/upro01]$ exec 6>&- #關閉fd 6描述符 [root@centos5 ~]$ ls /proc/self/fd/ 0 1 2 3
說明:使用前先將標準輸入保存到文件描述符6,這裏說明下,文件描述符默認會打開0,1,2 還可使用自定義描述符 。而後對標準輸出綁定到文件,接下來全部輸出都會發生到文件。 使用完後,恢復標準的輸出,關閉打開文件描述符6。
>&n 使用系統調用 dup2複製文件描述符 n 並把結果用做標準輸出; <&n 標準輸入複製自文件描述符 n; <&- 關閉標準輸入(鍵盤); >&- 關閉標準輸出; n<&- 表示將 n 號輸入關閉; n>&- 表示將 n 號輸出關閉; 上述全部形式均可之前導一個數字,此時創建的文件描述符由這個數字指定而不是缺省的 0 或 1。如: ... 2>file 運行一個命令並把錯誤輸出(文件描述符 2)定向到 file。 ... 2>&1 運行一個命令並把它的標準輸出和輸出合併。(嚴格的說是經過複製文件描述符 1 來創建文件描述符 2 ,但效果一般是合併了兩個流。) 我 們對 2>&1詳細說明一下 :2>&1 也就是 FD2=FD1 ,這裏並非說FD2 的值 等於FD1的值,由於 > 是改變送出的數據通道,也就是說把 FD2 的 「數據輸出通道」 改成 FD1 的 「數據輸出通道」。若是僅僅這樣,這個改變好像沒有什麼做用,由於 FD2 的默認輸出和 FD1的默認輸出原本都是 monitor,同樣的! 可是,當 FD1 是其餘文件,甚至是其餘 FD 時,這個就具備特殊的用途了。請你們務必理解這一點。 exec 1>outfilename # 打開文件outfilename做爲stdout。 exec 2>errfilename # 打開文件 errfilename做爲 stderr。 exec 0<&- # 關閉 FD0。 exec 1>&- # 關閉 FD1。 exec 5>&- # 關閉 FD5。
參考: