1. 程式人生 > >shell 輸出重定向(> >> 2>&1)

shell 輸出重定向(> >> 2>&1)

1、首先,bash中0,1,2三個數字分別代表STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO,即標準輸入(一般是鍵盤),標準輸出(一般是顯示屏,準確的說是使用者終端控制檯),標準錯誤(出錯資訊輸出)。

2、輸入輸出可以重定向,所謂重定向輸入就是在命令中指定具體的輸入來源,譬如 cat < test.c 將test.c重定向為cat命令的輸入源。輸出重定向是指定具體的輸出目標以替換預設的標準輸出,譬如ls > 1.txt將ls的結果從標準輸出重定向為1.txt文字。有時候會看到如 ls >> 1.txt這類的寫法,> 和 >> 的區別在於:> 用於新建而>>用於追加。即ls > 1.txt會新建一個1.txt檔案並且將ls的內容輸出到新建的1.txt中,而ls >> 1.txt則用在1.txt已經存在,而我們只是想將ls的內容追加到1.txt文字中的時候。

3、預設輸入只有一個(0,STDIN_FILENO),而預設輸出有兩個(標準輸出1 STDOUT_FILENO,標準錯誤2 STDERR_FILENO)。因此預設情況下,shell輸出的錯誤資訊會被輸出到2,而普通輸出資訊會輸出到1。但是某些情況下,我們希望在一個終端下看到所有的資訊(包括標準輸出資訊和錯誤資訊),要怎麼辦呢?

       對了,你可以使用我們上面講到的輸出重定向。思路有了,怎麼寫呢? 非常直觀的想法就是2>1(將2重定向到1嘛),行不行呢?試一試就知道了。我們進行以下測試步驟:

1)mkdir test && cd test                ; 建立test資料夾並進入test目錄

2)touch a.txt b.c c                          ; 建立a.txt b.c c 三個檔案

3)ls > 1                                           ; 按我們的猜測,這句應該是將ls的結果重定向到標準輸出,因此效果和直接ls應該一樣。但是實際這句執行後,標準輸出中並沒有任何資訊。

4)ls                                                  ; 執行3之後再次ls,則會看到test資料夾中多了一個檔案1

5)cat 1                                            ; 檢視檔案1的內容,實際結果為:1 a.txt b.c c     可見步驟3中 ls > 1並不是將ls的結果重定向為標準輸出,而是將結果重定向到了一個檔案1中。即1在此處不被解釋為STDOUT_FILENO,而是檔案1。

4、到了此時,你應該也能猜到2>&1的用意了。不錯,2>&1就是用來將標準錯誤2重定向到標準輸出1中的。此處1前面的&就是為了讓bash將1解釋成標準輸出而不是檔案1。至於最後一個&,則是讓bash在後臺執行

在字元終端環境中,標準輸入/標準輸出的概念很好理解。輸入即指對一個應用程式或命令的輸入,無論是從鍵盤輸入還是從別的檔案輸入;輸出即指應用程式或命令產生的一些資訊; Linux 系統下還有一個標準錯誤輸出的概念,這個概念主要是為程式除錯和系統維護目的而設定的,錯誤輸出於標準輸出分開可以讓一些高階的錯誤資訊不干擾正常的輸出資訊,從而方便一般使用者的使用。 在 Linux 系統中:標準輸入(stdin)預設為鍵盤輸入;標準輸出(stdout)預設為螢幕輸出;標準錯誤輸出(stderr)預設也是輸出到螢幕(上面的 std 表示 standard)。在 BASH 中使用這些概念時一般將標準輸出表示為 1,將標準錯誤輸出表示為 2。下面我們舉例來說明如何使用他們,特別是標準輸出和標準錯誤輸出。 Wei_Steven 收集整理 輸入、輸出及標準錯誤輸出主要用於 I/O 的重定向,就是說需要改變他們的預設設定。先看這個例子: $ ls > ls_result $ ls -l >> ls_result 上面這兩個命令分別將 ls 命令的結果輸出重定向到 ls_result 檔案中和追加到 ls_result 檔案中,而不是輸出到螢幕上。">"就是輸出(標準輸出和標準錯誤輸出)重定向的代表符號,連續兩個 ">" 符號,即 ">>" 則表示不清除原來的而追加輸出。下面再來看一個稍微複雜的例子: $ find /home -name lost* 2> err_result 這個命令在 ">" 符號之前多了一個 "2","2>" 表示將標準錯誤輸出重定向。由於 /home 目錄下有些目錄由於許可權限制不能訪問,因此會產生一些標準錯誤輸出被存放在 err_result 檔案中。大家可以設想一下 find /home -name lost* 2>>err_result 命令會產生什麼結果? 如果直接執行 find /home -name lost* > all_result ,其結果是隻有標準輸出被存入 all_result 檔案中,要想讓標準錯誤輸出和標準輸入一樣都被存入到檔案中,那該怎麼辦呢?看下面這個例子: $ find /home -name lost* > all_result 2>& 1 上面這個例子中將首先將標準錯誤輸出也重定向到標準輸出中,再將標準輸出重定向到 all_result 這個檔案中。這樣我們就可以將所有的輸出都儲存到檔案中了。為實現上述功能,還有一種簡便的寫法如下: $ find /home -name lost* >& all_result 如果那些出錯資訊並不重要,下面這個命令可以讓你避開眾多無用出錯資訊的干擾: $ find /home -name lost* 2> /dev/null 同學們回去後還可以再試驗一下如下幾種重定向方式,看看會出什麼結果,為什麼? $ find /home -name lost* > all_result 1>& 2 $ find /home -name lost* 2> all_result 1>& 2 $ find /home -name lost* 2>& 1 > all_result 另外一個非常有用的重定向操作符是 "-",請看下面這個例子

$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -) 該命令表示把 /source/directory 目錄下的所有檔案通過壓縮和解壓,快速的全部移動到 /dest/directory 目錄下去,這個命令在 /source/directory 和 /dest/directory 不處在同一個檔案系統下時將顯示出特別的優勢。 下面還幾種不常見的用法: n<&- 表示將 n 號輸入關閉 <&- 表示關閉標準輸入(鍵盤) n>&- 表示將 n 號輸出關閉 >&- 表示將標準輸出關閉