我們?cè)贚inux下經(jīng)常會(huì)碰到nohup command>/dev/ 2>&1 &
這樣形式的命令。首先我們把這條命令大概分解下首先就是一個(gè)nohup
命令可以在你退出帳戶之后繼續(xù)運(yùn)行相應(yīng)的進(jìn)程。nohup就是不掛起的意思( no hang up)。
&
是把該命令以后臺(tái)的job的形式運(yùn)行。那么就剩下command>/dev/ 2>&1,command>/dev/
較好理解,/dev/
表示一個(gè)空設(shè)備,就是說吧command的執(zhí)行結(jié)果重定向到空設(shè)備中,說白了就是不顯示任何信息。那么2>&1
又是什么含義?
>
代表重定向到哪里,例如:echo “123”>
/home/123.txt
/dev/ 表示空設(shè)備文件
0 表示stdin標(biāo)準(zhǔn)輸入
1 表示stdout標(biāo)準(zhǔn)輸出,系統(tǒng)默認(rèn)值是1,所以”>/dev/”等同于 “1>/dev/”
2 表示stderr標(biāo)準(zhǔn)錯(cuò)誤
其實(shí)這條命令是一個(gè)縮寫版,對(duì)于一個(gè)重定向命令,肯定是a > b
這種形式,那么command > /dev/
難道是command充當(dāng)a的角色,/dev/充當(dāng)b的角色。
這樣看起來比較合理,其實(shí)一條命令肯定是充當(dāng)不了a,肯定是command執(zhí)行產(chǎn)生的輸出來充當(dāng)a,其實(shí)就是標(biāo)準(zhǔn)輸出stdout。
所以command > /dev/
相當(dāng)于執(zhí)行了command 1 > /dev/
。執(zhí)行command產(chǎn)生了標(biāo)準(zhǔn)輸出stdout(用1表示),重定向到/dev/的設(shè)備文件中。
通過上面command > /dev/
等價(jià)于command 1 > /dev/
,那么對(duì)于2>&1
也就好理解了,2就是標(biāo)準(zhǔn)錯(cuò)誤,1是標(biāo)準(zhǔn)輸出,那么這條命令不就是相當(dāng)于把標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出么。等等是&1而不是1,這里&是什么?對(duì)于& 1
更準(zhǔn)確的說應(yīng)該是文件描述符 1,而1標(biāo)識(shí)標(biāo)準(zhǔn)輸出,stdout。這里&1相當(dāng)于等效于標(biāo)準(zhǔn)輸出,>
重定到標(biāo)準(zhǔn)輸出,這里標(biāo)準(zhǔn)輸出已經(jīng)重定向到了 /dev/。那么標(biāo)準(zhǔn)錯(cuò)誤也會(huì)輸出到/dev/。
通過上面的分析,對(duì)于command>a 2>&1
這條命令,等價(jià)于command 1>a 2>&1
可以理解為執(zhí)行command產(chǎn)生的標(biāo)準(zhǔn)輸入重定向到文件a中,標(biāo)準(zhǔn)錯(cuò)誤也重定向到文件a中。那么是否就說command 1>a 2>&1
等價(jià)于command 1>a 2>a
呢。其實(shí)不是,command 1>a 2>&1
與command 1>a 2>a
還是有區(qū)別的,區(qū)別就在于前者只打開一次文件a,后者會(huì)打開文件兩次,并導(dǎo)致stdout被stderr覆蓋。&1
的含義就可以理解為用標(biāo)準(zhǔn)輸出的引用,引用的就是重定向標(biāo)準(zhǔn)輸出產(chǎn)生打開的a。從IO效率上來講,command 1>a 2>&1
比command 1>a 2>a
的效率更高。
#!/bin/sh t date
chmod +x test.sh
為test.sh增加執(zhí)行權(quán)限。這里我們弄了兩條命令,其中t指令并不存在,執(zhí)行會(huì)報(bào)錯(cuò),會(huì)輸出到stderr。date能正常執(zhí)行,執(zhí)行會(huì)輸出當(dāng)前時(shí)間,會(huì)輸出到stdout。
執(zhí)行./test.sh > res1.log
結(jié)果為 我們發(fā)現(xiàn)stderr并沒有被重定向到res1.log中,stderr被打印到了屏幕上。這也進(jìn)一步證明了上面說的./test.sh > res1.log
等價(jià)于./test.sh 1>res1.log
執(zhí)行./test.sh>res2.log 2>&1
結(jié)果為 這次我們發(fā)現(xiàn)stdout和stderr都被重定向到了res2.log中了。上面我們未對(duì)stderr也就是2說明如何輸出,stderr就輸出到了屏 幕上,這里我們不僅對(duì)stdout進(jìn)行說明,重定向到res2.log中,對(duì)標(biāo)準(zhǔn)錯(cuò)誤也進(jìn)行了說明,讓其重定向到res2.log的引用即 res2.log的文件描述符中。
為何2>&1要寫在command>1的后面,直接用2可以么。比如ls 2>a
。其實(shí)這種用法也是可以的,ls命令列出當(dāng)前的目錄,用stdout(1)表示,由于這個(gè)時(shí)候沒有stderr(2),這個(gè)時(shí)候執(zhí)行l(wèi)s 2>a也會(huì)正常產(chǎn)生一個(gè)a的文件,但是a的文件中是空的,因?yàn)檫@時(shí)候執(zhí)行l(wèi)s并沒有產(chǎn)生stderr(2)。
AIOps 風(fēng)向標(biāo)
GOPS 2019 · 深圳站
一手掌握 BATJ 國(guó)內(nèi)大企技術(shù)前沿的好機(jī)會(huì)
4月12-13,相聚深圳
聯(lián)系客服