類型 | 文件描述符 | 默認(rèn)情況 | 對應(yīng)文件句柄位置 |
---|---|---|---|
標(biāo)準(zhǔn)輸入(standard input) | 0 | 從鍵盤獲得輸入 | /proc/self/fd/0 |
標(biāo)準(zhǔn)輸出(standard output) | 1 | 輸出到屏幕(即控制臺) | /proc/self/fd/1 |
錯誤輸出(error output) | 2 | 輸出到屏幕(即控制臺) | /proc/self/fd/2 |
所以我們平時在執(zhí)行shell命令中,都默認(rèn)是從鍵盤獲得輸入,并且將結(jié)果輸出到控制臺上。但是我們可以通過更改文件描述符默認(rèn)的指向,從而實現(xiàn)輸入輸出的重定向。比如我們將1指向文件,那么標(biāo)準(zhǔn)的輸出就會輸出到文件中。
輸出重定向
輸出重定向的使用方式很簡單,基本的一些命令如下:
命令 | 介紹 |
---|---|
command >filename | 把標(biāo)準(zhǔn)輸出重定向到新文件中 |
command 1>filename | 同上 |
command >>filename | 把標(biāo)準(zhǔn)輸出追加到文件中 |
command 1>>filename | 同上 |
command 2>filename | 把標(biāo)準(zhǔn)錯誤重定向到新文件中 |
command 2>>filename | 把標(biāo)準(zhǔn)錯誤追加到新文件中 |
我們使用>或者>>對輸出進(jìn)行重定向。符號的左邊表示文件描述符,如果沒有的話表示1,也就是標(biāo)準(zhǔn)輸出,符號的右邊可以是一個文件,也可以是一個輸出設(shè)備。當(dāng)使用>時,會判斷右邊的文件存不存在,如果存在的話就先刪除,然后創(chuàng)建一個新的文件,不存在的話則直接創(chuàng)建。但是當(dāng)使用>>進(jìn)行追加時,則不會刪除原來已經(jīng)存在的文件。
為了更好地理解輸出重定向,感受重定向的“魅力”,我們看一下以下的例子:我們創(chuàng)建一個測試目錄,目錄下面僅有一個a.txt文件。
# tree . └── a.txt 0 directories, 1 file # ls a.txt b.txt ls: 無法訪問b.txt: 沒有那個文件或目錄 a.txt
在我們執(zhí)行ls a.txt b.txt
之后,一共有兩種輸出,其中ls:
無法訪問b.txt: 沒有那個文件或目錄是錯誤輸出,a.txt是標(biāo)準(zhǔn)輸出。
# ls a.txt b.txt 1>out ls: 無法訪問b.txt: 沒有那個文件或目錄 # cat out a.txt # ls a.txt b.txt >>out ls: 無法訪問b.txt: 沒有那個文件或目錄 # cat out a.txt a.txt
在上述命令中,我們將原來的標(biāo)準(zhǔn)輸出重定向到了out文件中,所以控制臺只剩下了錯誤提示。并且當(dāng)執(zhí)行了追加操作時,out文件的內(nèi)容非但沒有被清空,反而又多了一條a.txt。
同理,我們也可以將錯誤輸出重定向到文件中:
# ls a.txt b.txt 2>err a.txt # cat err ls: 無法訪問b.txt: 沒有那個文件或目錄 # ls a.txt b.txt >out 2>err # cat out a.txt # cat err ls: 無法訪問b.txt: 沒有那個文件或目錄
看到這里,朋友們可能會發(fā)現(xiàn)>out 2>err
和我們在一開頭提到的>/dev/null 2>1
已經(jīng)很像了,別急,這待會再說。
輸入重定向
在理解了輸出重定向之后,理解輸入重定向就會容易得多。對輸入重定向的基本命令如下:
命令 | 介紹 |
---|---|
command filename | 以filename文件作為標(biāo)準(zhǔn)輸入 |
command 0filename | 同上 |
command delimiter | 從標(biāo)準(zhǔn)輸入中讀入,直到遇到delimiter分隔符 |
我們使用對輸入做重定向,如果符號左邊沒有寫值,那么默認(rèn)就是0。
我們這次以cat命令為例,如果cat后面沒有跟文件名的話,那它的作用就是將標(biāo)準(zhǔn)輸入(比如鍵盤)回顯到標(biāo)準(zhǔn)輸出(比如屏幕)上:
# cat 123 123 test test
我們可以將利用輸入重定向,將我們在鍵盤上敲入的字符寫入到文件中。我們需要使用ctrl+c來結(jié)束輸入:
# cat >out 123 test ^C # cat out 123 test
好了,此時我們覺得自己在鍵盤上敲比較累,還是直接讓cat讀取一個文件吧。那么我們需要利用輸入重定向:
# cat input aaa 111 # cat >out input # cat out aaa 111
神奇的事情發(fā)生了,out文件里面的內(nèi)容被替換成了input文件里的內(nèi)容。那么又是什么作用呢?我們再看:
# cat >out end > 123 > test > end # cat out 123 test
我們看到,當(dāng)我們輸入完cat >out end
,然后敲下回車之后,命令并沒有結(jié)束,此時cat命令像一開始一樣,等待你給它輸入數(shù)據(jù)。然后當(dāng)我們敲入end之后,cat命令就結(jié)束了。end之前輸入的字符都已經(jīng)被寫入到了out文件中。這就是輸入分割符的作用。
高級用法
重定向綁定
好了,在有了以上知識的基礎(chǔ)上,我們再來看開頭提到的>/dev/null 2>1
。這條命令其實分為兩命令,一個是>/dev/null
,另一個是2>1
。
1. >/dev/null
這條命令的作用是將標(biāo)準(zhǔn)輸出1重定向到/dev/null
中。 /dev/null
代表linux的空設(shè)備文件,所有往這個文件里面寫入的內(nèi)容都會丟失,俗稱“黑洞”。那么執(zhí)行了>/dev/null
之后,標(biāo)準(zhǔn)輸出就會不再存在,沒有任何地方能夠找到輸出的內(nèi)容。
2. 2>1
這條命令用到了重定向綁定,采用可以將兩個輸出綁定在一起。這條命令的作用是錯誤輸出將和標(biāo)準(zhǔn)輸出同用一個文件描述符,說人話就是錯誤輸出將會和標(biāo)準(zhǔn)輸出輸出到同一個地方。
linux在執(zhí)行shell命令之前,就會確定好所有的輸入輸出位置,并且從左到右依次執(zhí)行重定向的命令,所以>/dev/null 2>1
的作用就是讓標(biāo)準(zhǔn)輸出重定向到/dev/null
中(丟棄標(biāo)準(zhǔn)輸出),然后錯誤輸出由于重用了標(biāo)準(zhǔn)輸出的描述符,所以錯誤輸出也被定向到了/dev/null
中,錯誤輸出同樣也被丟棄了。執(zhí)行了這條命令之后,該條shell命令將不會輸出任何信息到控制臺,也不會有任何信息輸出到文件中。
>/dev/null 2>1 VS 2>1 >/dev/null
再回到文章的開頭,我說我弄反了>/dev/null
和2>1
拼裝的順序,導(dǎo)致出了一點(diǎn)小問題。乍眼看這兩條命令貌似是等同的,但其實大為不同。剛才提到了,linux在執(zhí)行shell命令之前,就會確定好所有的輸入輸出位置,并且從左到右依次執(zhí)行重定向的命令。那么我們同樣從左到右地來分析2>1 >/dev/null
:
2>1
,將錯誤輸出綁定到標(biāo)準(zhǔn)輸出上。由于此時的標(biāo)準(zhǔn)輸出是默認(rèn)值,也就是輸出到屏幕,所以錯誤輸出會輸出到屏幕。
>/dev/null
,將標(biāo)準(zhǔn)輸出1重定向到/dev/null
中。
我們用一個表格來更好地說明這兩條命令的區(qū)別:
命令 | 標(biāo)準(zhǔn)輸出 | 錯誤輸出 |
---|---|---|
>/dev/null 2>1 | 丟棄 | 丟棄 |
2>1 >/dev/null | 丟棄 | 屏幕 |
>/dev/null 2>1 VS >/dev/null 2>/dev/null
那么可能會有些同學(xué)會疑問,為什么要用重定向綁定,而不是像>/dev/null 2>/dev/null
這樣子重復(fù)一遍呢。
為了回答這個問題,我們回到剛才介紹輸出重定向的場景。我們嘗試將標(biāo)準(zhǔn)輸出和錯誤輸出都定向到out文件中:
# ls a.txt b.txt >out 2>out # cat out a.txt 無法訪問b.txt: 沒有那個文件或目錄
WTF?竟然出現(xiàn)了亂碼,這是為啥呢?這是因為采用這種寫法,標(biāo)準(zhǔn)輸出和錯誤輸出會搶占往out文件的管道,所以可能會導(dǎo)致輸出內(nèi)容的時候出現(xiàn)缺失、覆蓋等情況?,F(xiàn)在是出現(xiàn)了亂碼,有時候也有可能出現(xiàn)只有error信息或者只有正常信息的情況。不管怎么說,采用這種寫法,最后的情況是無法預(yù)估的。
而且,由于out文件被打開了兩次,兩個文件描述符會搶占性的往文件中輸出內(nèi)容,所以整體IO效率不如>/dev/null 2>1
來得高。
nohup結(jié)合
我們經(jīng)常使用nohup command
命令形式來啟動一些后臺程序,比如一些java服務(wù):
# nohup java -jar xxxx.jar
為了不讓一些執(zhí)行信息輸出到前臺(控制臺),我們還會加上剛才提到的>/dev/null 2>1
命令來丟棄所有的輸出:
# nohup java -jar xxxx.jar >/dev/null 2>1
總結(jié)
本文主要介紹了linux重定向的原理以及一些基本命令,并且詳細(xì)地分析了>/dev/null 2>1
這個命令以及一些注意點(diǎn)。
總而言之,在工作中用到最多的就是nohup command >/dev/null 2>1
命令,希望大家能夠好好掌握。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
標(biāo)簽:九江 新疆 贛州 懷化 北京 亳州 河南 惠州
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解shell中;/dev/null 2;&1到底是什么》,本文關(guān)鍵詞 詳解,shell,中,dev,null,amp,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。