(四)Linux Shell編程——輸入輸出重定向


Unix 命令默認從標准輸入設備(stdin)獲取輸入,將結果輸出到標准輸出設備(stdout)顯示。一般情況下,標准輸入設備就是鍵盤,標准輸出設備就是終端,即顯示器。

1. 輸出重定向

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

命令輸出重定向的語法為:

command > file

如:將用戶信息輸出到 test.sh文件中(test.sh文件中含有內容)

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

可以看到,輸出重定向會覆蓋文件內容,如果不希望文件內容被覆蓋,可以使用 >> 追加到文件末尾

[root@centoszang testShell]# echo "Hello EveryOne" >> test.sh
[root@centoszang 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

 這樣,本來需要從鍵盤獲取輸入的命令會轉移到文件讀取內容。

[root@centoszang testShell]# wc -l test.sh    #計算 test.sh 文件中的行數
3 test.sh
[root@centoszang 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文件

將 stdout 和 stderr 合並后重定向到 log

重定向到某個文件描述符時,必須在文件描述符前面添加 & 符號。必須這樣的原因:類似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會相互覆蓋。該命令執行時相當於兩個進程同時向同一個文件中寫數據,你寫你的,我寫我的,也不進行同步,寫完拉倒。打開文件一看,數據重疊,亂七八糟。

command > file 2>&1 命令把STDOUT直接送往file文件,而STDERR經由STDOUT的通道把數據信息送到file文件中。此時,file文件只被打開了一次,因此標准輸出數據和標准錯誤數據不會相互覆蓋,而是井然有序。

從I/O效率上來說,command > file 2> file 相比於 command > file 2>&1 要低,而且會出現數據相互覆蓋的情況。因此,我們一般會使用后面這條命令。

3.3 可用的重定向命令列表

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

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

 

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前后的空格會被忽略掉。

在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

另外,在只想刪除文件內容,而不刪除文件時,可以使用如下方法

 

 

參考:

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

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


免責聲明!

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



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