日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shell中的>/dev/null 2>1(转载)

發(fā)布時(shí)間:2023/12/31 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shell中的>/dev/null 2>1(转载) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

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

shell重定向介紹

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

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

文件描述符

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

類型文件描述符默認(rèn)情況對(duì)應(yīng)文件句柄位置
標(biāo)準(zhǔn)輸入(standard input)0從鍵盤獲得輸入/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)是從鍵盤獲得輸入,并且將結(jié)果輸出到控制臺(tái)上。但是我們可以通過更改文件描述符默認(rèn)的指向,從而實(shí)現(xiàn)輸入輸出的重定向。比如我們將1指向文件,那么標(biāo)準(zhǔn)的輸出就會(huì)輸出到文件中。

輸出重定向

輸出重定向的使用方式很簡單,基本的一些命令如下:

命令介紹
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)的左邊表示文件描述符,如果沒有的話表示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ì)刪除原來已經(jīng)存在的文件。

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

1

2

3

4

5

6

7

8

# tree

.

└── a.txt

?

0 directories, 1 file

# ls a.txt b.txt

ls: 無法訪問b.txt: 沒有那個(gè)文件或目錄

a.txt

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

1

2

3

4

5

6

7

8

9

# ls a.txt b.txt 1>out

ls: 無法訪問b.txt: 沒有那個(gè)文件或目錄

# cat out

a.txt

# ls a.txt b.txt >>out

ls: 無法訪問b.txt: 沒有那個(gè)文件或目錄

# cat out

a.txt

a.txt

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

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

1

2

3

4

5

6

7

8

9

# ls a.txt b.txt 2>err

a.txt

# cat err

ls: 無法訪問b.txt: 沒有那個(gè)文件或目錄

# ls a.txt b.txt >out 2>err

# cat out

a.txt

# cat err

ls: 無法訪問b.txt: 沒有那個(gè)文件或目錄

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

輸入重定向

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

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

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

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

1

2

3

4

5

# cat

123

123

test

test

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

1

2

3

4

5

6

7

# cat >out

123

test

^C

# cat out

123

test

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

1

2

3

4

5

6

7

# cat input

aaa

111

# cat >out <input

# cat out

aaa

111

神奇的事情發(fā)生了,out文件里面的內(nèi)容被替換成了input文件里的內(nèi)容。那么<<又是什么作用呢?我們?cè)倏?#xff1a;

1

2

3

4

5

6

7

# cat >out <<end

> 123

> test

> end

# cat out

123

test

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

高級(jí)用法

重定向綁定

好了,在有了以上知識(shí)的基礎(chǔ)上,我們?cè)賮砜撮_頭提到的>/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è)文件里面寫入的內(nèi)容都會(huì)丟失,俗稱“黑洞”。那么執(zhí)行了>/dev/null之后,標(biāo)準(zhǔn)輸出就會(huì)不再存在,沒有任何地方能夠找到輸出的內(nèi)容。

2. 2>&1

這條命令用到了重定向綁定,采用&可以將兩個(gè)輸出綁定在一起。這條命令的作用是錯(cuò)誤輸出將和標(biāo)準(zhǔn)輸出同用一個(gè)文件描述符,說人話就是錯(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

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

  • 2>&1,將錯(cuò)誤輸出綁定到標(biāo)準(zhǔn)輸出上。由于此時(shí)的標(biāo)準(zhǔn)輸出是默認(rèn)值,也就是輸出到屏幕,所以錯(cuò)誤輸出會(huì)輸出到屏幕。
  • >/dev/null,將標(biāo)準(zhǔn)輸出1重定向到/dev/null中。
  • 我們用一個(gè)表格來更好地說明這兩條命令的區(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ì)疑問,為什么要用重定向綁定,而不是像>/dev/null 2>/dev/null這樣子重復(fù)一遍呢。

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

    1

    2

    3

    4

    # ls a.txt b.txt >out 2>out

    # cat out

    a.txt

    �法訪問b.txt: 沒有那個(gè)文件或目錄

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

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

    nohup結(jié)合

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

    1

    # nohup java -jar xxxx.jar &

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

    1

    # 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 &命令,希望大家能夠好好掌握。

    參考資料

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

    以上是生活随笔為你收集整理的shell中的>/dev/null 2>1(转载)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。