當我們在shell中執行命令的時候,每個進程都和三個打開的文件相聯系,並使用文件描述符來引用這些文件。由於文件描述符不容易記憶,shell同時也給出了相應的文件名。
下面就是這些文件描述符及它們通常所對應的文件名:
文件文件描述符
系統中實際上有12個文件描述符,但是正如我們在上表中所看到的, 0、1、2是標准輸入、輸出和錯誤。可以任意使用文件描述符3到9。
標准輸入是文件描述符0。它是命令的輸入,缺省是鍵盤,也可以是文件或其他命令的輸出。
標准輸出是文件描述符1。它是命令的輸出,缺省是屏幕,也可以是文件。
標准錯誤是文件描述符2。這是命令錯誤的輸出,缺省是屏幕,同樣也可以是文件。
你可能會問,為什么會有一個專門針對錯誤的特殊文件?這是由於很多人喜歡把錯誤單獨保存到一個文件中,特別是在處理大的數據文件時,可能會產生很多錯誤。
如果沒有特別指定文件說明符,命令將使用缺省的文件說明符(你的屏幕,更確切地說是你的終端)。
文件重定向
在執行命令時,可以指定命令的標准輸入、輸出和錯誤,要實現這一點就需要使用文件重定向。下表列出了最常用的重定向組合,並給出了相應的文件描述符。
在對標准錯誤進行重定向時,必須要使用文件描述符,但是對於標准輸入和輸出來說,這不是必需的。
command << delimiter 把從標准輸入中讀入,直至遇到delimiter分界符
command <&m 把把文件描述符m作為標准輸入
command >&m 把把標准輸出重定向到文件描述符m中
command <&- 把關閉標准輸入 //?這個“-”代表什么意思
重定向標准輸出
讓我們來看一個標准輸出的例子。在下面的命令中,把/etc/passwd文件中的用戶ID域按照用戶命排列。
該命令的輸出重定向到sort.out文件中。要提醒注意的是,在使用sort命令的時候(或其他含有相似輸入文件參數的命令),重定向符號一定要離開sort命令兩個空格,否則該命令會把它當作輸入文件。
$ cat passwd | awk -F: '{print $1}' | sort 1>sort.out //錯誤信息不會輸出到sort.out
也可以使用如下的表達方式,結果和上面一樣:
$ cat passwd | awk -F: '{print $1}' | sort >sort.out //與上面的等價,什么也不寫的>,默認就是1【標准輸出】
可以把很多命令的輸出追加到同一文件中。
如果希望把標准輸出重定向到文件中,可以用>filename。在下面的例子中,ls命令的所有輸出都被重定向到ls.out文件中:
$ ls >ls.out
如果想創建一個長度為0的空文件,可以用>filename:
$ >myfile
重定向標准輸入
可以指定命令的標准輸入。在awk一章就會遇到這樣的情況。下面給出一個這樣的例子:
$ sort < name.txt
在上面的命令中, sort命令的輸入是采用重定向的方式給出的,不過也可以直接把相應的
文件作為該命令的參數:
$ sort name.txt
在上面的例子中,還可以更進一步地通過重定向為sort命令指定一個輸出文件name.out。
這樣屏幕上將不會出現任何信息(除了錯誤信息以外):
$ sort <name.txt >name.out
在發送郵件時,可以用重定向的方法發送一個文件中的內容。在下面的例子中,用戶
louise將收到一個郵件,其中含有文件contents.txt中的內容:
$ mail louise < contents.txt
重定向操作符command << delimiter是一種非常有用的命令,通常都被稱為“此處”文擋。
shell將分界符delimiter之后直至下一個同樣的分界符之前的所有內容都作為輸入,遇到下一個分界符,shell就知道輸入結束了。
這一命令對於自動或遠程的例程非常有用。可以任意定義分界符delimiter,最常見的是EOF,而我最喜歡用MAYDAY,這完全取決於個人的喜好。還可以在<<后面輸入變量。
下面給出一個例子,我們創建了一個名為myfile的文件,並在其中使用了TERM和LOGNAME變量。
$cat >> myfile <<MAYDAY //直到遇到字符串“MAYDAY”,會停止輸入 > Hello there I am using a $TERIM terminal > and my user name is $LOGNAME > bye... > MAYDAY
$ cat myfile Hello there I am using a vt100 terminal and my user name is dave bye...
重定向標准錯誤
為了重定向標准錯誤,可以指定文件描述符2。
grep命令沒有找到該文件,缺省地向終端輸出了一個錯誤信息。現在讓我們把錯誤重定向到文件/dev/null中(實際就上是系統的垃圾箱):
$ grep "trident" missiles 2>/dev/null
這樣所有的錯誤輸出都輸送到了/dev/null,不再出現在屏幕上。
合並標准輸出和標准錯誤
在合並標准輸出和標准錯誤的時候,切記shell是從左至右分析相應的命令的。下面給出一個例子:
$ cleanup >cleanup.out 2>&1
在上面的例子中,我們將cleanup 腳本的輸出重定向到>cleanup.out文件中,而且其錯誤也被重定向到相同的文件中。
$ grep "standard"* > grep.out 2>&1
在上面的例子中,grep命令的標准輸出和標准錯誤都被重定向到grep.out文件中。你在使出前面提到的“此處”文擋時,有可能需要把所有的輸出都保存到一個文件中,這樣萬一出現了錯誤,就能夠被記錄下來。通過使用2 > & 1就可以做到這一點
http://blog.sina.com.cn/s/blog_51dc0fba0100lqgb.html
shell中可能經常能看到:>/dev/null 2>&1 //即忽略所以輸出信息。
詳解:
標准輸出【不寫即為標准輸出1】的內容輸出到/dev/null【recycle bin】,2【標准錯誤】的內容輸出到1【標准輸出】的位置即【recycle bin】
eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print $4}'` 1>/dev/null 2>/dev/null
或eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print $4}'` >/dev/null 2>&1

命令的結果可以通過%>的形式來定義輸出
/dev/null 代表空設備文件,即recycle bin,比windows的回收站更徹底,即少了清空回收站這一步
> 代表重定向到哪里,例如:echo "123" > /home/123.txt
1 表示 stdout標准輸出,系統 默認值是1,所以">/dev/null" 等同於" 1>/dev/null"
2 表示 stderr標准錯誤
& 表示等同於的意思,2>&1,表示2的輸出重定向等同於1,即和1重定向的文件系統上的位置是一樣的
那么本文標題的語句:
1>/dev/null 首先表示標准輸出重定向到空設備文件,也就是不輸出任何信息到終端,說白了就是不顯示任何信息。
2>&1 接着,標准錯誤輸出重定向等同於 標准輸出,因為之前標准輸出已經重定向到了空設備文件,所以標准錯誤輸出也重定向到空設備文件。
Shell會自動為我們打開和關閉0、1、2這三個文件描述符,我們不需要顯式地打開或關閉它們。標准輸入是命令的輸入,默認指向鍵盤;標准輸出是命令的輸出,默認指向屏幕;標准錯誤是命令錯誤信息的輸出,默認指向屏幕。
如果沒有顯式地進行重定向,命令通過文件描述符0從屏幕讀取輸入,通過文件描述符1和2將輸出和錯誤信息輸出到屏幕。但如果我們想從其他文件(再次強調,I/O設備在Unix/Linux中也是文件)讀取輸入或產生輸出,就需要對0、1、2使用重定向了。其語法如下:
command < filename 把標准輸入重定向到filename文件中
command 0< filename 同上
command > filename 把標准輸出重定向到filename文件中(覆蓋)
command 1> fielname 同上
command >> filename 把標准輸出重定向到filename文件中(追加)
command 1>> filename 同上
command 2> filename 把標准錯誤重定向到filename文件中(覆蓋)
command 2>> filename 同上
command > filename 2>&1 把標准輸出和標准錯誤一起重定向到filename文件中(覆蓋)
command >> filename 2>&1 把標准輸出和標准錯誤一起重定向到filename文件中(追加)
command < filename >filename2 把文件filename中的內容作為command的輸入,把標准輸出重定向到filename2文件中
command 0< filename 1> filename2 同上
重定向的使用有如下規律:
1)標准輸入0、輸出1、錯誤2需要分別重定向,一個重定向只能改變它們中的一個。
2)標准輸入0和標准輸出1可以省略。(當其出現重定向符號左側時)
3)文件描述符在重定向符號左側時直接寫即可,在右側時前面加& 【類似於指針前要加*號,來區分這、兩種情況】。
4)文件描述符與重定向符號之間不能有空格!