文件描述符(0、1、2)的用法

前面的[2] 尖括號教程中[3],你看到了如何使用 >,如下:

  1. ls > list.txt

ls 輸出傳遞給 list.txt 文件。

現在我們看到的是簡寫:

  1. ls 1> list.txt

在這種情況下,1 是一個文件描述符,指向標準輸出(stdout)。

以類似的方式,2 指向標準錯誤輸出(stderr):

  1. ls 2> error.log

所有錯誤消息都通過管道傳遞給 error.log 文件。

回顧一下:1> 是標準輸出(stdout),2> 是標準錯誤輸出(stderr)。

第三個標準文件描述符,0< 是標準輸入(stdin)。你可以看到它是一個輸入,因爲箭頭(<)指向0,而對於 12,箭頭(>)是指向外部的。

標準文件描述符有什麼用?

如果你在閱讀本系列以後,你已經多次使用標準輸出(1>)的簡寫形式:>

例如,當(假如)你知道你的命令會拋出一個錯誤時,像 stderr2)這樣的東西也很方便,但是 Bash 告訴你的東西是沒有用的,你不需要看到它。如果要在 home/ 目錄中創建目錄,例如:

  1. mkdir newdir

如果 newdir/ 已經存在,mkdir 將顯示錯誤。但你爲什麼要關心這些呢?(好吧,在某些情況下你可能會關心,但並非總是如此。)在一天結束時,newdir 會以某種方式讓你填入一些東西。你可以通過將錯誤消息推入虛空(即 ``/dev/null`)來抑制錯誤消息:

  1. mkdir newdir 2> /dev/null

===========================================================================

這不僅僅是 “讓我們不要看到醜陋和無關的錯誤消息,因爲它們很煩人”,因爲在某些情況下,錯誤消息可能會在其他地方引起一連串錯誤。比如說,你想找到 /etc 下所有的 .service 文件。你可以這樣做:

  1. find /etc -iname "*.service"

但事實證明,在大多數系統中,find 顯示的錯誤會有許多行,因爲普通用戶對 /etc 下的某些文件夾沒有讀取訪問權限。它使讀取正確的輸出變得很麻煩,如果 find 是更大的腳本的一部分,它可能會導致行中的下一個命令排隊。

相反,你可以這樣做:

  1. find /etc -iname "*.service" 2> /dev/null

而且你只得到你想要的結果。

單獨的文件描述符 stdoutstderr 還有一些注意事項。如果要將輸出存儲在文件中,請執行以下操作:

  1. find /etc -iname "*.service" 1> services.txt

工作正常,因爲 1> 意味着 “發送標準輸出且自身標準輸出(非標準錯誤)到某個地方”。

但這裏存在一個問題:如果你想把命令拋出的錯誤信息記錄到文件,而結果中沒有錯誤信息你該怎麼做?上面的命令並不會這樣做,因爲它只寫入 find 正確的結果,而:

  1. find /etc -iname "*.service" 2> services.txt

只會寫入命令拋出的錯誤信息。

我們如何得到兩者?請嘗試以下命令:

  1. find /etc -iname "*.service" &> services.txt

</pre>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章