shell重定向介紹及使用


我們在寫腳本或用腳本時,往往會發現 > /dev/null 2>&1 這類的命令。之前都是簡單的了解一下,並沒有深度消化,直到自己寫腳本時,不認真寫成了2>&1 >/dev/null,導致結果出問題。下面我通過網絡給大家介紹一下:

shell重定向介紹:

我們平時寫的腳本或啟動程序,某段代碼會處理外部的輸入,然后將調用傳參指行命令結果輸出到屏幕或指定的位置。在交互式的腳本中,輸入來自用戶的鍵盤和鼠標,結果輸出到用戶的屏幕或設備中。而對於某些后台運行的啟動腳本或程序,這些都會統統寫到日志文件里。

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

文件描述符:

執行shell命令中,默認是從鍵盤獲得輸入,並且將結果輸出到控制台上。但是我們可以通過更改文件描述符默認的指向,從而實現輸入輸出的重定向;比如我們將1指向文件,那么標准的輸出就會輸出到文件中。

輸出重定向:

>或1> 重定向,會清除文件里所有以前數據,增加新數據。

>>或1>> 追加重定向,文件結尾加入內容,不會刪除已有的內容。

我們使用>或者>>對輸出進行重定向。符號的左邊表示文件描述符,如果沒有的話表示1,也就是標准輸出,符號的右邊可以是一個文件,也可以是一個輸出設備。當使用>時,會判斷右邊的文件存不存在,如果存在的話就先刪除,然后創建一個新的文件,不存在的話則直接創建。但是當使用>>進行追加時,則不會刪除原來已經存在的文件。

測試:

執行ls 001.txt 002.log之后,一共有兩種輸出,其中ls: 無法訪問002.log: 沒有那個文件或目錄是錯誤輸出,001.txt是標准輸出。

執行ls 001.txt 002.log >>a.log 將原來的標准輸出重定向到了a.log文件中,所以控制台只剩下了錯誤提示。並且當執行了追加操作時,a.log文件的內容非但沒有被清空,反而又多了一條001.txt

同理,我們也可將錯誤輸出重定向到指定文件中:

 輸入重定向:

使用<對輸入做重定向,如果符號左邊沒有寫值,那么默認就是0。

以cat命令為例,如果cat后面沒有跟文件名的話,那它的作用就是將標准輸入(鍵入)回顯到標准輸出(屏幕)上:

利用輸入重定向,將在鍵盤上輸入的字符寫入到文件中;ctrl+c來結束輸入:

 

有時候,我們需要讀取一個文件,並寫入另一個文件,那么我們可以利用輸入重定向:

 

神奇的事情發生了,error.log文件里面的內容被替換成了a.log文件里的內容。那么<<又是什么作用呢?我們再看:

當我們輸入完cat >error.log <<bqh,然后敲下回車之后,命令並沒有結束,此時cat命令像一開始一樣,等待你給它輸入數據。然后當我們敲入end之后,cat命令就結束了。bqh之前輸入的字符都已經被寫入到了out文件中。這就是輸入分割符的作用。

高級用法:重定向綁定

>/dev/null  

這條命令的作用是將標准輸出1重定向到/dev/null中。/dev/null代表linux的空設備文件,所有往這個文件里面寫入的內容都會丟失,俗稱“黑洞”。那么執行了>/dev/null之后,標准輸出就會不再存在,沒有任何地方能夠找到輸出的內容。

2>&1  

這條命令用到了重定向綁定,采用&可以將兩個輸出綁定在一起。這條命令的作用是錯誤輸出將和標准輸出同用一個文件描述符,說人話就是錯誤輸出將會和標准輸出輸出到同一個地方。  

linux在執行shell命令之前,就會確定好所有的輸入輸出位置,並且從左到右依次執行重定向的命令,所以>/dev/null 2>&1的作用就是讓標准輸出重定向到/dev/null中(丟棄標准輸出),然后錯誤輸出由於重用了標准輸出的描述符,所以錯誤輸出也被定向到了/dev/null中,錯誤輸出同樣也被丟棄了。執行了這條命令之后,該條shell命令將不會輸出任何信息到控制台,也不會有任何信息輸出到文件中。

>/dev/null 2>&1 與 2>&1 >/dev/null 區別

這兩條命令貌似是等同的,但其實大為不同,linux在執行shell命令之前,就會確定好所有的輸入輸出位置,並且從左到右依次執行重定向的命令,那么我們同樣從左到右地來分析2>&1 >/dev/null:

2>&1,將錯誤輸出綁定到標准輸出上。由於此時的標准輸出是默認值,也就是輸出到屏幕,所以錯誤輸出會輸出到屏幕,>/dev/null,將標准輸出1重定向到/dev/null中(黑洞)。

>/dev/null 2>&1 與 >/dev/null 2>/dev/null 的剖析:

那么可能會有些人會疑問,為什么要用重定向綁定,而不是像>/dev/null 2>/dev/null這樣子重復一遍呢。  為了回答這個問題,我們回到剛才介紹輸出重定向的場景。我們嘗試將標准輸出和錯誤輸出都定向到a.log文件中:

納尼?竟然出現了亂碼,這是為啥呢?這是因為采用這種寫法,標准輸出和錯誤輸出會搶占往a.log文件的管道,所以可能會導致輸出內容的時候出現缺失、覆蓋等情況。現在是出現了亂碼,有時候也有可能出現只有error信息或者只有正常信息的情況。不管怎么說,采用這種寫法,最后的情況是無法預估很糟糕的。而且,由於a.log文件被打開了兩次,兩個文件描述符會搶占性的往文件中輸出內容,所以整體IO效率不如>/dev/null 2>&1來得高。

總而言之,在工作中用到最多的就是nohup command >/dev/null 2>&1 命令

參考資料:

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

2、(輸入重定向與輸出重定向)詳細分析

3、>/dev/null 2>&1 和 2>&1 >/dev/null的區別


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM