shell中> /dev/null 2 > &1是什么鬼蚁滋?

背景

我們經(jīng)常能在shell腳本中發(fā)現(xiàn)>/dev/null 2>&1這樣的語(yǔ)句。以前的我并沒(méi)有去深入地理解這段命令的作用合陵,照搬照用枢赔,直到上周我將這段命令不小心寫(xiě)成了2>&1 >/dev/null,出了一點(diǎn)小問(wèn)題之后拥知,我才開(kāi)始去了解這段命令背后的“玄機(jī)”踏拜。

shell重定向介紹

就像我們平時(shí)寫(xiě)的程序一樣,一段程序會(huì)處理外部的輸入低剔,然后將運(yùn)算結(jié)果輸出到指定的位置速梗。在交互式的程序中,輸入來(lái)自用戶的鍵盤(pán)和鼠標(biāo)襟齿,結(jié)果輸出到用戶的屏幕姻锁,甚至播放設(shè)備中。而對(duì)于某些后臺(tái)運(yùn)行的程序猜欺,輸入可能來(lái)自于外部的一些文件位隶,運(yùn)算的結(jié)果通常又寫(xiě)到其他的文件中。而且程序在運(yùn)行的過(guò)程中开皿,會(huì)有一些關(guān)鍵性的信息涧黄,比如異常堆棧篮昧,外部接口調(diào)用情況等,這些都會(huì)統(tǒng)統(tǒng)寫(xiě)到日志文件里笋妥。

shell腳本也一樣懊昨,但是我們一般在使用shell命令的時(shí)候,更多地還是通過(guò)鍵盤(pán)輸入春宣,然后在屏幕上查看命令的執(zhí)行結(jié)果酵颁。如果某些情況下,我們需要將shell命令的執(zhí)行結(jié)果存儲(chǔ)到文件中月帝,那么我們就需要使用輸入輸出的重定向功能躏惋。

文件描述符

當(dāng)執(zhí)行shell命令時(shí),會(huì)默認(rèn)打開(kāi)3個(gè)文件嫁赏,每個(gè)文件有對(duì)應(yīng)的文件描述符來(lái)方便我們使用:

類型 文件描述符 默認(rèn)情況 對(duì)應(yīng)文件句柄位置
標(biāo)準(zhǔn)輸入(standard input) 0 從鍵盤(pán)獲得輸入 /proc/slef/fd/0
標(biāo)準(zhǔn)輸出(standard output) 1 輸出到屏幕(即控制臺(tái)) /proc/slef/fd/1
錯(cuò)誤輸出(error output) 2 輸出到屏幕(即控制臺(tái)) /proc/slef/fd/2

所以我們平時(shí)在執(zhí)行shell命令中其掂,都默認(rèn)是從鍵盤(pán)獲得輸入油挥,并且將結(jié)果輸出到控制臺(tái)上潦蝇。但是我們可以通過(guò)更改文件描述符默認(rèn)的指向,從而實(shí)現(xiàn)輸入輸出的重定向深寥。比如我們將1指向文件攘乒,那么標(biāo)準(zhǔn)的輸出就會(huì)輸出到文件中。

輸出重定向

輸出重定向的使用方式很簡(jiǎ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)錯(cuò)誤重定向到新文件中
command 2>>filename 把標(biāo)準(zhǔn)錯(cuò)誤追加到新文件中

我們使用>或者>>對(duì)輸出進(jìn)行重定向则酝。符號(hào)的左邊表示文件描述符,如果沒(méi)有的話表示1闰集,也就是標(biāo)準(zhǔn)輸出沽讹,符號(hào)的右邊可以是一個(gè)文件,也可以是一個(gè)輸出設(shè)備武鲁。當(dāng)使用>時(shí)爽雄,會(huì)判斷右邊的文件存不存在,如果存在的話就先刪除沐鼠,然后創(chuàng)建一個(gè)新的文件挚瘟,不存在的話則直接創(chuàng)建。但是當(dāng)使用>>進(jìn)行追加時(shí)饲梭,則不會(huì)刪除原來(lái)已經(jīng)存在的文件乘盖。

為了更好地理解輸出重定向,感受重定向的“魅力”憔涉,我們看一下以下的例子:我們創(chuàng)建一個(gè)測(cè)試目錄订框,目錄下面僅有一個(gè)a.txt文件。

# tree
.
└── a.txt

0 directories, 1 file
# ls a.txt b.txt
ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄
a.txt

在我們執(zhí)行ls a.txt b.txt之后兜叨,一共有兩種輸出穿扳,其中ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄是錯(cuò)誤輸出藤违,a.txt是標(biāo)準(zhǔn)輸出。

# ls a.txt b.txt 1>out
ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄
# cat out
a.txt
# ls a.txt b.txt >>out
ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄
# cat out
a.txt
a.txt

在上述命令中纵揍,我們將原來(lái)的標(biāo)準(zhǔn)輸出重定向到了out文件中顿乒,所以控制臺(tái)只剩下了錯(cuò)誤提示。并且當(dāng)執(zhí)行了追加操作時(shí)泽谨,out文件的內(nèi)容非但沒(méi)有被清空璧榄,反而又多了一條a.txt

同理吧雹,我們也可以將錯(cuò)誤輸出重定向到文件中:

# ls a.txt b.txt 2>err
a.txt
# cat err
ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄
# ls a.txt b.txt >out 2>err
# cat out
a.txt
# cat err
ls: 無(wú)法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄

看到這里骨杂,朋友們可能會(huì)發(fā)現(xiàn)>out 2>err和我們?cè)谝婚_(kāi)頭提到的>/dev/null 2>&1已經(jīng)很像了,別急雄卷,這待會(huì)再說(shuō)搓蚪。

輸入重定向

在理解了輸出重定向之后,理解輸入重定向就會(huì)容易得多丁鹉。對(duì)輸入重定向的基本命令如下:

命令 介紹
command <filename 以filename文件作為標(biāo)準(zhǔn)輸入
command 0<filename 同上
command <<delimiter 從標(biāo)準(zhǔn)輸入中讀入妒潭,直到遇到delimiter分隔符

我們使用<對(duì)輸入做重定向,如果符號(hào)左邊沒(méi)有寫(xiě)值揣钦,那么默認(rèn)就是0雳灾。

我們這次以cat命令為例,如果cat后面沒(méi)有跟文件名的話冯凹,那它的作用就是將標(biāo)準(zhǔn)輸入(比如鍵盤(pán))回顯到標(biāo)準(zhǔn)輸出(比如屏幕)上:

# cat
123
123
test
test

我們可以將利用輸入重定向谎亩,將我們?cè)阪I盤(pán)上敲入的字符寫(xiě)入到文件中。我們需要使用ctrl+c來(lái)結(jié)束輸入:

# cat >out
123
test
^C
# cat out
123
test

好了宇姚,此時(shí)我們覺(jué)得自己在鍵盤(pán)上敲比較累匈庭,還是直接讓cat讀取一個(gè)文件吧。那么我們需要利用輸入重定向:

# cat input
aaa
111
# cat >out <input
# cat out
aaa
111

神奇的事情發(fā)生了浑劳,out文件里面的內(nèi)容被替換成了input文件里的內(nèi)容阱持。那么<<又是什么作用呢?我們?cè)倏矗?/p>

# cat >out <<end
> 123
> test
> end
# cat out
123
test

我們看到呀洲,當(dāng)我們輸入完cat >out <<end紊选,然后敲下回車之后,命令并沒(méi)有結(jié)束道逗,此時(shí)cat命令像一開(kāi)始一樣兵罢,等待你給它輸入數(shù)據(jù)。然后當(dāng)我們敲入end之后滓窍,cat命令就結(jié)束了卖词。end之前輸入的字符都已經(jīng)被寫(xiě)入到了out文件中。這就是輸入分割符的作用。

高級(jí)用法

重定向綁定

好了此蜈,在有了以上知識(shí)的基礎(chǔ)上即横,我們?cè)賮?lái)看開(kāi)頭提到的>/dev/null 2>&1。這條命令其實(shí)分為兩命令裆赵,一個(gè)是>/dev/null东囚,另一個(gè)是2>&1

1. >/dev/null

這條命令的作用是將標(biāo)準(zhǔn)輸出1重定向到/dev/null中战授。/dev/null代表linux的空設(shè)備文件页藻,所有往這個(gè)文件里面寫(xiě)入的內(nèi)容都會(huì)丟失,俗稱“黑洞”植兰。那么執(zhí)行了>/dev/null之后份帐,標(biāo)準(zhǔn)輸出就會(huì)不再存在,沒(méi)有任何地方能夠找到輸出的內(nèi)容楣导。

2. 2>&1

這條命令用到了重定向綁定废境,采用&可以將兩個(gè)輸出綁定在一起。這條命令的作用是錯(cuò)誤輸出將和標(biāo)準(zhǔn)輸出同用一個(gè)文件描述符筒繁,說(shuō)人話就是錯(cuò)誤輸出將會(huì)和標(biāo)準(zhǔn)輸出輸出到同一個(gè)地方噩凹。

linux在執(zhí)行shell命令之前,就會(huì)確定好所有的輸入輸出位置膝晾,并且從左到右依次執(zhí)行重定向的命令栓始,所以>/dev/null 2>&1的作用就是讓標(biāo)準(zhǔn)輸出重定向到/dev/null中(丟棄標(biāo)準(zhǔn)輸出),然后錯(cuò)誤輸出由于重用了標(biāo)準(zhǔn)輸出的描述符血当,所以錯(cuò)誤輸出也被定向到了/dev/null中,錯(cuò)誤輸出同樣也被丟棄了禀忆。執(zhí)行了這條命令之后臊旭,該條shell命令將不會(huì)輸出任何信息到控制臺(tái),也不會(huì)有任何信息輸出到文件中箩退。

>/dev/null 2>&1 VS 2>&1 >/dev/null

再回到文章的開(kāi)頭离熏,我說(shuō)我弄反了>/dev/null2>&1拼裝的順序,導(dǎo)致出了一點(diǎn)小問(wèn)題戴涝。乍眼看這兩條命令貌似是等同的滋戳,但其實(shí)大為不同。剛才提到了啥刻,linux在執(zhí)行shell命令之前奸鸯,就會(huì)確定好所有的輸入輸出位置,并且從左到右依次執(zhí)行重定向的命令可帽。那么我們同樣從左到右地來(lái)分析2>&1 >/dev/null

  1. 2>&1娄涩,將錯(cuò)誤輸出綁定到標(biāo)準(zhǔn)輸出上。由于此時(shí)的標(biāo)準(zhǔn)輸出是默認(rèn)值映跟,也就是輸出到屏幕蓄拣,所以錯(cuò)誤輸出會(huì)輸出到屏幕扬虚。
  2. >/dev/null,將標(biāo)準(zhǔn)輸出1重定向到/dev/null中球恤。

我們用一個(gè)表格來(lái)更好地說(shuō)明這兩條命令的區(qū)別:

命令 標(biāo)準(zhǔn)輸出 錯(cuò)誤輸出
>/dev/null 2>&1 丟棄 丟棄
2>&1 >/dev/null 丟棄 屏幕

>/dev/null 2>&1 VS >/dev/null 2>/dev/null

那么可能會(huì)有些同學(xué)會(huì)疑問(wèn)辜昵,為什么要用重定向綁定,而不是像>/dev/null 2>/dev/null這樣子重復(fù)一遍呢咽斧。

為了回答這個(gè)問(wèn)題路鹰,我們回到剛才介紹輸出重定向的場(chǎng)景。我們嘗試將標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出都定向到out文件中:

# ls a.txt b.txt >out 2>out
# cat out
a.txt
?法訪問(wèn)b.txt: 沒(méi)有那個(gè)文件或目錄

WTF收厨?竟然出現(xiàn)了亂碼晋柱,這是為啥呢?這是因?yàn)椴捎眠@種寫(xiě)法诵叁,標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出會(huì)搶占往out文件的管道雁竞,所以可能會(huì)導(dǎo)致輸出內(nèi)容的時(shí)候出現(xiàn)缺失、覆蓋等情況∨《睿現(xiàn)在是出現(xiàn)了亂碼碑诉,有時(shí)候也有可能出現(xiàn)只有error信息或者只有正常信息的情況。不管怎么說(shuō)侥锦,采用這種寫(xiě)法进栽,最后的情況是無(wú)法預(yù)估的。

而且恭垦,由于out文件被打開(kāi)了兩次快毛,兩個(gè)文件描述符會(huì)搶占性的往文件中輸出內(nèi)容,所以整體IO效率不如>/dev/null 2>&1來(lái)得高番挺。

nohup結(jié)合

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

# nohup java -jar xxxx.jar &

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

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

總結(jié)

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

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

參考資料

  1. linux重定向總結(jié)
  2. >/dev/null 2>&1 和 2>&1 >/dev/null的區(qū)別

小問(wèn)題

接著本文的場(chǎng)景,下面命令徘意,錯(cuò)誤輸出會(huì)輸出到什么地方呢苔悦?同學(xué)們可以在評(píng)論區(qū)留言回答哦~

# ls a.txt b.txt 2>&1 >/dev/null 2>&1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市映砖,隨后出現(xiàn)的幾起案子间坐,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竹宋,死亡現(xiàn)場(chǎng)離奇詭異劳澄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蜈七,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)秒拔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人飒硅,你說(shuō)我怎么就攤上這事砂缩。” “怎么了三娩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵庵芭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我雀监,道長(zhǎng)双吆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任会前,我火速辦了婚禮好乐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瓦宜。我一直安慰自己蔚万,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布临庇。 她就那樣靜靜地躺著反璃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苔巨。 梳的紋絲不亂的頭發(fā)上版扩,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音侄泽,去河邊找鬼。 笑死蜻韭,一個(gè)胖子當(dāng)著我的面吹牛悼尾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肖方,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闺魏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了俯画?” 一聲冷哼從身側(cè)響起析桥,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后泡仗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體埋虹,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年娩怎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搔课。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡截亦,死狀恐怖爬泥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崩瓤,我是刑警寧澤袍啡,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站却桶,受9級(jí)特大地震影響境输,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肾扰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一畴嘶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧集晚,春花似錦窗悯、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至莲绰,卻和暖如春欺旧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛤签。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工辞友, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人震肮。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓称龙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親戳晌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鲫尊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • Ubuntu的發(fā)音 Ubuntu,源于非洲祖魯人和科薩人的語(yǔ)言搔驼,發(fā)作 oo-boon-too 的音谈火。了解發(fā)音是有意...
    螢火蟲(chóng)de夢(mèng)閱讀 99,274評(píng)論 9 467
  • linux資料總章2.1 1.0寫(xiě)的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 12,168評(píng)論 2 33
  • 默認(rèn)情況下,總是有三個(gè)文件處于打開(kāi)狀態(tài)匙奴,標(biāo)準(zhǔn)輸入(鍵盤(pán)輸入)堆巧、標(biāo)準(zhǔn)輸出(輸出到屏幕)、標(biāo)準(zhǔn)錯(cuò)誤(也是輸出到屏幕)泼菌,...
    owen_he閱讀 594評(píng)論 0 0
  • 本文筆記源自這里——[實(shí)驗(yàn)樓]歡迎大家在下面交流其中有問(wèn)題的地方喜歡請(qǐng)點(diǎn)收藏谍肤,每日更新(全部已親自實(shí)踐). 一. ...
    東皇Amrzs閱讀 3,992評(píng)論 7 54
  • 2017.712 星期四 晴 親子日記(80) 今天忙了一天,挺累的哗伯,但要堅(jiān)持啊荒揣,為了給孩子做個(gè)榜樣,今天的日...
    于澤媽媽閱讀 116評(píng)論 0 0