shell中>/dev/null?2>&1

背景


我們經(jīng)常能在shell腳本中發(fā)現(xiàn)>/dev/null 2>&1這樣的語句。以前的我并沒有去深入地理解這段命令的作用,照搬照用隐孽,直到上周我將這段命令不小心寫成了2>&1 >/dev/null绊诲,出了一點小問題之后抗俄,我才開始去了解這段命令背后的“玄機(jī)”跟压。


shell重定向介紹


就像我們平時寫的程序一樣,一段程序會處理外部的輸入钾虐,然后將運算結(jié)果輸出到指定的位置。在交互式的程序中,輸入來自用戶的鍵盤和鼠標(biāo)瘦锹,結(jié)果輸出到用戶的屏幕听绳,甚至播放設(shè)備中。而對于某些后臺運行的程序,輸入可能來自于外部的一些文件,運算的結(jié)果通常又寫到其他的文件中。而且程序在運行的過程中,會有一些關(guān)鍵性的信息,比如異常堆棧,外部接口調(diào)用情況等米绕,這些都會統(tǒng)統(tǒng)寫到日志文件里。


shell腳本也一樣,但是我們一般在使用shell命令的時候贵白,更多地還是通過鍵盤輸入,然后在屏幕上查看命令的執(zhí)行結(jié)果崩泡。如果某些情況下角撞,我們需要將shell命令的執(zhí)行結(jié)果存儲到文件中谒所,那么我們就需要使用輸入輸出的重定向功能。


文件描述符


當(dāng)執(zhí)行shell命令時梆造,會默認(rèn)打開3個文件镇辉,每個文件有對應(yīng)的文件描述符來方便我們使用:


類型 文件描述符 默認(rèn)情況 對應(yīng)文件句柄位置

標(biāo)準(zhǔn)輸入(standard input) 0 從鍵盤獲得輸入 /proc/slef/fd/0

標(biāo)準(zhǔn)輸出(standard output) 1 輸出到屏幕(即控制臺) /proc/slef/fd/1

錯誤輸出(error output) 2 輸出到屏幕(即控制臺) /proc/slef/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í)行l(wèi)s a.txt b.txt之后扯饶,一共有兩種輸出,其中l(wèi)s: 無法訪問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 0<filename 同上

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)致出了一點小問題允粤。乍眼看這兩條命令貌似是等同的,但其實大為不同翼岁。剛才提到了类垫,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文件中:


1

2

3

4

# 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)缺失县忌、覆蓋等情況。現(xiàn)在是出現(xiàn)了亂碼,有時候也有可能出現(xiàn)只有error信息或者只有正常信息的情況症杏。不管怎么說装获,采用這種寫法,最后的情況是無法預(yù)估的厉颤。


而且穴豫,由于out文件被打開了兩次,兩個文件描述符會搶占性的往文件中輸出內(nèi)容逼友,所以整體IO效率不如>/dev/null 2>&1來得高绩郎。


nohup結(jié)合


我們經(jīng)常使用nohup command &命令形式來啟動一些后臺程序,比如一些java服務(wù):


1

# nohup java -jar xxxx.jar &

為了不讓一些執(zhí)行信息輸出到前臺(控制臺)翁逞,我們還會加上剛才提到的>/dev/null 2>&1命令來丟棄所有的輸出:


1

# nohup java -jar xxxx.jar >/dev/null 2>&1 &

總結(jié)


本文主要介紹了linux重定向的原理以及一些基本命令,并且詳細(xì)地分析了>/dev/null 2>&1這個命令以及一些注意點溉仑。


總而言之挖函,在工作中用到最多的就是nohup command >/dev/null 2>&1 &命令,希望大家能夠好好掌握浊竟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怨喘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子振定,更是在濱河造成了極大的恐慌必怜,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件后频,死亡現(xiàn)場離奇詭異梳庆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卑惜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門膏执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人露久,你說我怎么就攤上這事更米。” “怎么了毫痕?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵征峦,是天一觀的道長。 經(jīng)常有香客問我消请,道長栏笆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任臊泰,我火速辦了婚禮竖伯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己七婴,他們只是感情好祟偷,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著打厘,像睡著了一般修肠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上户盯,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天嵌施,我揣著相機(jī)與錄音,去河邊找鬼莽鸭。 笑死吗伤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的硫眨。 我是一名探鬼主播足淆,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼礁阁!你這毒婦竟也來了巧号?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姥闭,失蹤者是張志新(化名)和其女友劉穎丹鸿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棚品,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡靠欢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铜跑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掺涛。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疼进,靈堂內(nèi)的尸體忽然破棺而出薪缆,到底是詐尸還是另有隱情,我是刑警寧澤伞广,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布拣帽,位于F島的核電站,受9級特大地震影響嚼锄,放射性物質(zhì)發(fā)生泄漏减拭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一区丑、第九天 我趴在偏房一處隱蔽的房頂上張望拧粪。 院中可真熱鬧修陡,春花似錦、人聲如沸可霎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癣朗。三九已至拾因,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旷余,已是汗流浹背绢记。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留正卧,地道東北人蠢熄。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像炉旷,于是被迫代替她去往敵國和親签孔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容