shell程序中 2> /dev/null 代表什麼意思?

如題 2&> 代表什麼意思?將錯誤輸出刪除?

如果有正確的輸出並賦值給i,i會得到正確的值嗎?


以下來自一個重度linux使用患者不請自來的回答。

先用簡單的語言回答題主的問題:

shell程序中 2&> /dev/null 代表什麼意思?

答:「2&> /dev/null」 代表忽略掉錯誤提示信息。

如題 2&> 代表什麼意思?講錯誤輸出刪除?

答:「2&>」 代表重定向操作錯誤提示信息。只有這兩個字元並不能刪除錯誤輸出。

如果有正確的輸出並賦值給i,i會得到正確的值嗎?

答:i會得到正確的值。

上面的三個回答是我認為相對比較友好,容易理解的回答。

---------------------------------------我是啰哩啰唆回答的分割線-------------------------------------

2016-12-12 更新錯誤描述與更新排版

下面,咱們一起來看看這個命令操作涉及到的知識點(敲黑板。。。。)題主問題里描述的這條命令其實涉及到三部分的內容,如下圖:

(原諒我奇怪的畫風……)

下面的所有回到都是假設大家對linux沒有太多的了解所作的,如有高手,打臉的時候請輕一點。+_+

1. 文件描述符

下面手打一段《linux shell腳本攻略》的描述(如有侵權我會刪除的 T_T):

文件描述符是與文件輸入、輸出關聯的整數。它們用來跟蹤已打開的文件。最常見的文件描述符是stidin、stdout、和stderr。我們可以將某個文件描述符的內容重定向到另外一個文件描述符中。

《linux shell腳本攻略》

文件描述符我們常見的就是系統預留的0,1和2這三個,他們的意義分別有如下對應關係:

  • 0 —— stdin(標準輸入)

  • 1 —— stdout (標準輸出)

  • 2 —— stderr (標準錯誤)

其中,shell編程里經常用到的就是描述符1,和描述符2。這樣下面我們來舉兩個栗子,就知道神馬是1和2了:

1 —— stdout

假設:在當前目錄下我們「有且只有」一個文件名為 123.txt 的文本文件。這個時候我們運行下面的命令【ls 123.txt】:

我們就會獲得一個標準輸出stdout的輸出結果「123.txt」 。

2 —— stderr

按照上面同樣的假設,我們運行另外一跳命令【ls abc.txt】:

我們就會獲得一個標準錯誤stderr的輸出結果「ls:無法訪問abc.txt:沒有那個文件或目錄」。

有同學應該會覺得,這兩個事例好像跟1和2這兩個阿拉伯數字好像沒有關係。這個就要結合第二個知識點「重定向操作」來理解了。

2.重定向操作

書里找不到準確的關於重定向的描述,我很不要臉滴來說一下我的理解吧。重定向操作,其實就是通過在shell命令後面追加一個重定向操作符號,將shell命令對應的文件描述符輸出的文本信息重新輸入到另外一個指定文件的操作。

重定向操作符號有兩個&>和&>&>。儘管這兩個操作符都可以將重定向到文件,但是前者會先清空文件,再寫入內容;後者會將內容追加到現有文件的尾部。(對了,重定向的操作制定的文件如果原來不存在的話,重定向的操作會主動創建這個文件名的文件的)

下面我們結合第1個知識點文件描述符來舉栗子吧。

重定向標準輸出stdout

如上圖所示,對比沒有添加重定向的操作,ls命令在使用之後並沒有將字元「123.txt」這個字元串列印到屏幕上。在緊接著的cat操作之後,我們可以看到本來應該輸出字元串被記錄在了stdout.txt這個文件裡面了。

其實,對於標準輸出的重定向操作,&>等同於1&>。上面栗子執行命令【ls 123.txt &> stdout.txt】得到的效果也是一樣的。

重定向標準錯誤stderr

如上圖所示,文件描述符2,標準錯誤的重定向也是同樣的原理被記錄在了文件stderr.txt這個文件裡面了。描述符的重定向還有下面的幾種用法:

你可以將stderr單獨定向到一個文件,將stdout重定向到另一個文件:

cmd 2&>stderr.txt 1&>stdout.txt

也可以利用下面的方法,將stderr轉換成stdout,使得stderr和stdout都被重新定向到同一個文件中:

cmd&> output.txt 2&>1

或者採用這個方法(這個經常用到,我個人比較喜歡用這個,少寫幾個字元(*^__^*) )

cmd &> output.txt
cmd &> output.txt # 兩個表達式效果一樣噠~

(終於最後一個知識點,原來認真答題碼字這麼嘞。摔~)

3. linux特殊文件

手抄一段《linux shell腳本攻略》描述:

/dev/null是一個特殊的設備文件,這個文件接收到的任何數據都會被丟棄。因此,null這個設備通常也被成為位桶(bit bucket)或黑洞。

簡單地理解就是,重定向操作給這個/dev/null文件的所有東西都會被丟棄。

因為這些文件描述符輸出的字元串,總是會顯示出來的。如果我們在shell編程的時候,操作到某一條命令的返回結果,我們不想要這個時候又不想讓這個輸出結果列印到屏幕上(列印錯誤,多不好看對不對^_^)我們就可以重定向到/dev/null這個文件來,由/dev/null這個文件負責處理後事。

這個丟棄的結果又不能粗暴的認為是刪除錯誤輸出,這個操作是一個丟棄重定向輸入輸出的操作。

形象地理解就是,ATM機列印的紙質流水賬單(stdout和stderr)本來應該你來保存處理的,但是你又沒有用放在手裡(列印屏幕)又礙事,所以賬單從你的手裡重新被丟到了垃圾桶(/dev/null)了。但是,垃圾桶的垃圾是怎麼處理的你是不知道的。

不知道上面的描述,答主是不是能明白這三個知識點了?只要理解了上面的三個點,其實答主的第三個問題很好滴能解決了。

問題3的思路

讓一個變數獲得命令輸出的結果,是下面這樣的處理:

i=$(ls 123.txt)

這樣,i 就能獲得命令【ls 123.txt】輸出的標準輸出。錯誤提示(標準錯誤)依然會列印到屏幕上顯示。(萬分感謝 @張超 同學在評論中指正的我的錯誤^_^)

針對答主的問題,應該是如下操作:

i=$(ls 123.txt 2&> /dev/null)

這樣的命令,ls命令如果出現了錯誤提示,就會被重定向到/dev/null垃圾桶去了。所以,屏幕上不會列印任何輸出關於錯誤的提示字元。在這個命令的操作中,i 獲得文件stdout標準輸出,也就是文件述符1的屏幕輸出結果"123.txt"。

如果,這個123.txt文件不存在,i 就肯定什麼都拿不到,因為錯誤提示被/dev/null 吃了(劃掉),被重定向丟棄了屏幕也不顯示錯誤提示。所以,i 就是個什麼都沒有的空變數。基本就是如下效果一樣:

i=""

天吶,不知不覺答題竟然答了一個晚上。第一次答題這麼認真,走過路過的鄉親們,請賞個贊吧……碼字好累啊……(/ □ )


意思是把標準錯誤流(stderr)重定向到設備/dev/null上。

/dev/null 是類Unix系統中的一個特殊文件設備,他的作用是接受一切輸入它的數據並丟棄這些數據。通常被當做垃圾桶來用。

將輸出流重定向到它上面,就是丟棄這個輸出流上的所有輸出。

嘗試從/dev/null讀取數據,會立刻得到一個EOF。

順便,類Unix系統中,0代表標準輸入流(stdin),1代表標準輸出流(stdout),2代表標準錯誤流(stderr)。


將執行過程中不想看到的輸出信息丟到垃圾桶。這樣說直白不


鳥哥的 Linux 私房菜 -- 第十章、認識與學習BASH


stdin是0

stdout是1

stderr是2

&> 是重定向w

/dev/null 是個只進不出的地方


丟棄stderr輸出.


推薦閱讀:

對於爹媽這些不太懂電腦的人,有哪些簡單優秀操作系統備份還原軟體可以供他們使用?
到什麼程度才叫精通 Linux?
elementary OS 號稱最美 Linux ,哪個 Linux 發行版比較好看呢?
相對於其它發行版,選擇 Debian 的理由是什麼?
這裡有多少人脫離 Windows 完全使用 Linux?你花了多少時間適應?

TAG:Linux | Shell編程開發 | Linux開發 | Linux內核 | Shell語言 |