天天看點

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

Unix 指令預設從标準輸入裝置(stdin)擷取輸入,将結果輸出到标準輸出裝置(stdout)顯示。一般情況下,标準輸入裝置就是鍵盤,标準輸出裝置就是終端,即顯示器。

1. 輸出重定向

指令的輸出不僅可以是顯示器,還可以很容易的轉移向到檔案,這被稱為輸出重定向。

指令輸出重定向的文法為:

command > file      

如:将使用者資訊輸出到 test.sh檔案中(test.sh檔案中含有内容)

[[email protected] testShell]# ls
choose.sh  menuChoose  myShell.sh  test.sh
[[email protected] testShell]# who > test.sh
[[email protected] testShell]# cat test.sh 
root     tty1         2018-06-18 08:44 (:0)
root     pts/0        2018-06-18 14:55 (192.168.177.1)      

可以看到,輸出重定向會覆寫檔案内容,如果不希望檔案内容被覆寫,可以使用 >> 追加到檔案末尾

[[email protected] testShell]# echo "Hello EveryOne" >> test.sh
[[email protected] testShell]# cat test.sh 
root     tty1         2018-06-18 08:44 (:0)
root     pts/0        2018-06-18 14:55 (192.168.177.1)
Hello EveryOne      

2. 輸入重定向

和輸出重定向一樣,Unix 指令也可以從檔案擷取輸入。

command < file      

 這樣,本來需要從鍵盤擷取輸入的指令會轉移到檔案讀取内容。

[[email protected] testShell]# wc -l test.sh    #計算 test.sh 檔案中的行數
3 test.sh
[[email protected] testShell]# wc -l < test.sh
3      

上面兩個例子的結果不同:第一個例子,會輸出檔案名;第二個不會,因為它僅僅知道從标準輸入讀取内容。

3. 重定向深入講解

3.1 基本介紹

一般情況下,每個 Unix/Linux 指令運作時都會打開三個檔案:

  • 标準輸入檔案(stdin):stdin的檔案描述符為0,Unix程式預設從stdin讀取資料。
  • 标準輸出檔案(stdout):stdout 的檔案描述符為1,Unix程式預設向stdout輸出資料。
  • 标準錯誤檔案(stderr):stderr的檔案描述符為2,Unix程式會向stderr流中寫入錯誤資訊。

預設情況下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向或追加到 file,可以按照如下文法:

command 2> file   #重定向
command 2 >> file   #追加      

如下代碼是将标準錯誤資訊(stderr)也輸出到log檔案

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

将 stdout 和 stderr 合并後重定向到 log

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

重定向到某個檔案描述符時,必須在檔案描述符前面添加 & 符号。必須這樣的原因:類似1,2這樣的檔案描述符也是标準的Linux檔案名稱,添加 & 符号以做區分。

3.2 兩種(合并)重定向的差別

考慮當我們将stdout和stderr輸出時,command > file 2> file 與 command > file 2>&1 這兩種文法效果一樣嗎?

效果貌似一樣:因為不管是command産生的标準輸出資訊還是标準錯誤資訊都重定向到了file檔案裡。确實如此,但也有讓人意料之外的地方:

command > file 2> file 指令把STDOUT和STDERR都直接送到file檔案中,file檔案會被打開兩次,這樣STDOUT和STDERR會互相覆寫。該指令執行時相當于兩個程序同時向同一個檔案中寫資料,你寫你的,我寫我的,也不進行同步,寫完拉倒。打開檔案一看,資料重疊,亂七八糟。

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

command > file 2>&1 指令把STDOUT直接送往file檔案,而STDERR經由STDOUT的通道把資料資訊送到file檔案中。此時,file檔案隻被打開了一次,是以标準輸出資料和标準錯誤資料不會互相覆寫,而是井然有序。

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

從I/O效率上來說,command > file 2> file 相比于 command > file 2>&1 要低,而且會出現資料互相覆寫的情況。是以,我們一般會使用後面這條指令。

3.3 可用的重定向指令清單
(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

3.4 在同一指令中進行多次輸出重定向

 如果我們在同一個指令中進行了多次輸出重定向操作,會出現什麼情況呢?最終指令的輸出會重定向到最後一次重定向的位置。

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

echo hello world > log.txt 1>/dev/tty1 2>&1 指令首先把标準輸出重定向到log.txt檔案,由于目前目錄下并不存在該檔案,是以會建立該檔案,并把檔案清空;接着指令又把标準輸出重定向到了終端顯示器;最後又把标準錯誤重定向到了标準輸出。是以指令的輸出還是被發送到了終端顯示器上,指令結束,檔案關閉,結果log.txt檔案裡什麼資料都沒有寫入,隻是建立了一個空白的檔案。

4. Here Document

Here Document 目前沒有統一的翻譯,這裡暫譯為”嵌入文檔“。Here Document 是 Shell 中的一種特殊的重定向方式。

文法:

command << delimiter
    document
delimiter      

它的作用是将兩個 delimiter 之間的内容(document) 作為輸入傳遞給 command。

注意:

  • 結尾的delimiter 一定要頂格寫,前面不能有任何字元,後面也不能有任何字元,包括空格和 tab 縮進。
  • 開始的delimiter前後的空格會被忽略掉。
(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

在shell腳本中調用vi編輯器,輸入的内容由here document來提供。

#! /bin/bash
vi abc.txt <<EOF
i                        #進入insert模式
Here is a document!      #輸入文本内容
^[                       #這個符号是在Ctrl+v下按ESC鍵,意為按下ESC退出編輯模式
:wq                      #儲存退出
EOF      

需要注意的是,vi編輯器為互動式編輯器,一般不用在shell腳本中使用,除非有特殊需求。一般在shell腳本中都調用ed編輯器。

5. /dev/null 檔案

 如果希望執行某個指令,但又不希望在螢幕上顯示輸出結果,那麼可以将輸出重定向到 /dev/null。

文法:

command > /dev/null      

/dev/null 是一個特殊的檔案,寫入到它的内容都會被丢棄;如果嘗試從該檔案讀取内容,那麼什麼也讀不到。但是 /dev/null 檔案非常有用,将指令的輸出重定向到它,會起到”禁止輸出“的效果。在隻想測試指令而不想有任何輸出時較有用。

command > /dev/null 2>&1   #屏蔽 stdout 和 stderr      
(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

另外,在隻想删除檔案内容,而不删除檔案時,可以使用如下方法

(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案

參考:

https://www.cnblogs.com/pyhou/p/7650938.html

http://blog.51cto.com/callmebb/1300348

繼續閱讀