在 前面的[2] 尖括號教程中[3],你看到了如何使用 >
,如下:
ls > list.txt
將 ls 輸出傳遞給 list.txt
文件。
現在我們看到的是簡寫:
ls 1> list.txt
在這種情況下,1
是一個文件描述符,指向標準輸出(stdout
)。
以類似的方式,2
指向標準錯誤輸出(stderr
):
ls 2> error.log
所有錯誤消息都通過管道傳遞給 error.log
文件。
回顧一下:1>
是標準輸出(stdout
),2>
是標準錯誤輸出(stderr
)。
第三個標準文件描述符,0<
是標準輸入(stdin
)。你可以看到它是一個輸入,因爲箭頭(<
)指向0
,而對於 1
和 2
,箭頭(>
)是指向外部的。
標準文件描述符有什麼用?
如果你在閱讀本系列以後,你已經多次使用標準輸出(1>
)的簡寫形式:>
。
例如,當(假如)你知道你的命令會拋出一個錯誤時,像 stderr
(2
)這樣的東西也很方便,但是 Bash 告訴你的東西是沒有用的,你不需要看到它。如果要在 home/
目錄中創建目錄,例如:
mkdir newdir
如果 newdir/
已經存在,mkdir 將顯示錯誤。但你爲什麼要關心這些呢?(好吧,在某些情況下你可能會關心,但並非總是如此。)在一天結束時,newdir
會以某種方式讓你填入一些東西。你可以通過將錯誤消息推入虛空(即 ``/dev/null`)來抑制錯誤消息:
mkdir newdir 2> /dev/null
===========================================================================
這不僅僅是 “讓我們不要看到醜陋和無關的錯誤消息,因爲它們很煩人”,因爲在某些情況下,錯誤消息可能會在其他地方引起一連串錯誤。比如說,你想找到 /etc
下所有的 .service
文件。你可以這樣做:
find /etc -iname "*.service"
但事實證明,在大多數系統中,find 顯示的錯誤會有許多行,因爲普通用戶對 /etc
下的某些文件夾沒有讀取訪問權限。它使讀取正確的輸出變得很麻煩,如果 find 是更大的腳本的一部分,它可能會導致行中的下一個命令排隊。
相反,你可以這樣做:
find /etc -iname "*.service" 2> /dev/null
而且你只得到你想要的結果。
單獨的文件描述符 stdout
和 stderr
還有一些注意事項。如果要將輸出存儲在文件中,請執行以下操作:
find /etc -iname "*.service" 1> services.txt
工作正常,因爲 1>
意味着 “發送標準輸出且自身標準輸出(非標準錯誤)到某個地方”。
但這裏存在一個問題:如果你想把命令拋出的錯誤信息記錄到文件,而結果中沒有錯誤信息你該怎麼做?上面的命令並不會這樣做,因爲它只寫入 find 正確的結果,而:
find /etc -iname "*.service" 2> services.txt
只會寫入命令拋出的錯誤信息。
我們如何得到兩者?請嘗試以下命令:
find /etc -iname "*.service" &> services.txt
</pre>