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檔案

将 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 可用的重定向指令清單
(四)Linux Shell程式設計——輸入輸出重定向1. 輸出重定向2. 輸入重定向3. 重定向深入講解4. Here Document5. /dev/null 檔案
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