資料流重定向

2puT發表於2016-07-26
資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
資料流重定向
實驗介紹
你可能對重定向這個概念感到些許陌生,但你應該在前面的課程中多
次見過 > 或 >> 操作了,並知道他們分別是將標準輸出導向一個檔案或
追加到一個檔案中。這其實就是重定向,將原本輸出到標準輸出的數
據重定向到一個檔案中,因為標準輸出( /dev/stdout )本身也是一個
檔案,我們將命令輸出導向另一個檔案自然也是沒有任何問題的。
一、資料流重定向
下面我們簡單的回顧一下我們前面經常用到的兩個重定向操作:
$ echo 'hello shiyanlou' > redirect
$ echo 'www.shiyanlou.com' >> redirect
$ cat redirect
當然前面沒有用到的 < 和 << 操作也是沒有問題的,如你理解的
一樣,它們的區別在於重定向的方向不一致而已, > 表示是從
左到右, < 右到左。
1.簡單的重定向
在更多瞭解 Linux 的重定向之前,我們需要先知道一些基本的東西,
前面我們已經提到過 Linux 預設提供了三個特殊裝置,用於終端的顯
示和輸出,分別為 stdin (標準輸入,對應於你在終端的輸
入), stdout (標準輸出,對應於終端的輸出), stderr (標準錯
誤輸出,對應於終端的輸出)。
檔案描述符裝置檔案
1 of 8
說明
0 /dev/stdin 標準輸入
1 /dev/stdout 標準輸出
2 /dev/stderr 標準錯誤
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
檔案描述符:檔案描述符在形式上是一個非負整數。實際上,
它是一個索引值,指向核心為每一個程式所維護的該程式開啟
檔案的記錄表。當程式開啟一個現有檔案或者建立一個新檔案
時,核心向程式返回一個檔案描述符。在程式設計中,一些涉
及底層的程式編寫往往會圍繞著檔案描述符展開。但是檔案描
述符這一概念往往只適用於 UNIX、Linux 這樣的作業系統。
另外還有一個符號 - ,它可以同時作為前一個命令的。
我們可以這樣使用這些檔案描述符:
預設使用終端的標準輸入作為命令的輸入和標準輸出作為命令的輸出
$ cat
(按 Ctrl + C 退出)
將cat的連續輸出(heredoc方式)重定向到一個檔案
$ mkdir Documents
$ cat > Documents/test.c\~ <<EOF
#include <stdio.h>
int main()
{
printf ( "hello world\n" );
return 0 ;
}
EOF
將一個檔案作為命令的輸入,標準輸出作為命令的輸出
$ cat Documents /test.c\~
將echo命令通過管道傳過來的資料作為cat命令的輸入,將標準輸出作
為命令的輸出
$ echo 'hi' | cat
將echo命令的輸出從預設的標準輸出重定向到一個普通檔案
$ echo 'hello shiyanlou' > redirect
$ cat redirect
2 of 8
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
初學者這裡要注意不要將管道和重定向混淆,管道預設是連線前一個
命令的輸出到下一個命令的輸入,而重定向通常是需要一個檔案來建
立兩個命令的連線,你可以仔細體會一下上述第三個操作和最後兩個
操作的異同點。
2.標準錯誤重定向
重定向標準輸出到檔案,這是一個很實用的操作,另一個很實用的操
作是將標準錯誤重定向,標準輸出和標準錯誤都被指向偽終端的螢幕
顯示,所以我們經常看到的一個命令的輸出通常是同時包含了標準輸
出和標準錯誤的結果的。比如下面的操作:
# 使用cat 命令同時讀取兩個檔案,其中一個存在,另一個不
存在
$ cat Documents /test.c\~ hello.c
# 你可以看到除了正確輸出了前一個檔案的內容,還在末尾出現
了一條錯誤資訊
# 下面我們將輸出重定向到一個檔案,根據我們前面的經驗,這
裡將在看不到任何輸出了
$ cat Documents /test.c\~ hello.c > somefile
遺憾的是,這裡依然出現了那條錯誤資訊,這正是因為如我上面說的
那樣,標準輸出和標準錯誤雖然都指向終端螢幕,實際它們並不一
樣。那有的時候我們就是要可以隱藏某些錯誤或者警告,那又該怎麼
做呢。這就需要用到我們前面講的檔案描述符了:
3 of 8
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
# 將標準錯誤重定向到標準輸出,再將標準輸出重定向到檔案,
注意要將重定向到檔案寫到前面
$ cat Documents /test.c\~ hello.c >somefile 2 >& 1
# 或者只用bash提供的特殊的重定向符號"&"將標準錯誤和標準
輸出同時重定向到檔案
$ cat Documents /test.c\~ hello.c &>somefilehell
注意你應該在輸出重定向檔案描述符前加上 & ,否則shell會當做重定向
到一個檔名為1的檔案中
3.使用 tee 命令同時重定向到多個檔案
經常你可能還有這樣的需求,除了將需要將輸出重定向到檔案之外也
需要將資訊列印在終端,那麼你可以使用 tee 命令來實現:
$ echo 'hello shiyanlou' | tee hello
4.永久重定向
你應該可以看出我們前面的重定向操作都只是臨時性的,即只對當前
命令有效,那如何做到“永久”有效呢,比如在一個指令碼中,你需要某一
部分的命令的輸出全部進行重定向,難道要讓你在每個命令上面加上
臨時重定向的操作嘛,當然不需要,我們可以使用 exec 命令實現“永
久”重定向。 exec 命令的作用是使用指定的命令替換當前的 Shell,及
使用一個程式替換當前程式,或者指定新的重定向:
4 of 8
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
# 先開啟一個子 Shell
$ zsh
# 使用exec替換當前程式的重定向,將標準輸出重定向到一個
檔案
$ exec 1 >somefile
# 後面你執行的命令的輸出都將被重定向到檔案中,直到你退出
當前子shell,或取消exec的重定向(後面將告訴你怎麼做)
$ ls
$ exit
$ cat somefile
5.建立輸出檔案描述符
預設在 Shell 中可以有9個開啟的檔案描述符,上面我們使用了也是它
預設提供的 0 , 1 , 2 號檔案描述符,另外我們還可以使用3-8的檔案描
述符,只是它們預設沒有開啟而已,你可以使用下面命令檢視當前
Shell 程式中開啟的檔案描述符:
$ cd /dev/fd/;ls -Al
同樣使用 exec 命令可以建立新的檔案描述符:
$ zsh
$ exec 3 >somefile
# 先進入目錄,再檢視,否則你可能不能得到正確的結果,然後
再回到上一次的目錄
$ cd /dev/fd/;ls - Al ;cd -
# 注意下面的命令>與&之間不應該有空格,如果有空格則會出錯
$ echo "this is test" >& 3
$ cat somefile
$ exit
5 of 8
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
6.關閉檔案描述符
如上面我們開啟的3號檔案描述符,可以使用如下操作將它關閉:
$ exec 3 >&-
$ cd /dev/fd;ls -Al; cd -
7.完全遮蔽命令的輸出
在 Linux 中有一個被成為“黑洞”的裝置檔案,所以匯入它的資料都將被
“吞噬”。
在類 UNIX 系統中,/dev/null,或稱空裝置,是一個特殊的設
備檔案,它通常被用於丟棄不需要的輸出流,或作為用於輸入
流的空檔案,這些操作通常由重定向完成。讀取它則會立即得
到一個EOF。
我們可以利用設個 /dev/null 遮蔽命令的輸出:
$ cat Documents/test.c\~ nefile 1 > /dev/null 2 >& 1
向上面這樣的操作將使你得不到任何輸出結果。
8.使用 xargs 分割引數列表
xargs 是一條 UNIX 和類 UNIX 作業系統的常用命令。它的作
用是將引數列表轉換成小塊分段傳遞給其他命令,以避免引數
列表過長的問題。
這個命令在有些時候十分有用,特別是當用來處理產生大量輸出結果
的命令如 find,locate 和 grep 的結果,詳細用法請參看 man 文件。
$ cut -d : -f 1 < /etc/passwd | sort | xargs echo
6 of 8
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
上面這個命令用於將 /etc/passwd 檔案按 : 分割取第一個欄位排序
後,使用 echo 命令生成一個列表。
作業
1、理解下面這段程式碼的的作用,實際這段程式碼不會正常工作,請結合
這一小節的知識分析這段程式碼沒有正確工作的原因,並設法解決這個
問題。
如果你還沒有 Shell 指令碼程式設計的基礎,你可以選擇跳過或者到
這裡高階 Bash 程式設計指南 (http://www.shiyanlou.com/courses
/5)學習
while read filename; do
rm -iv $filename
done <<(ls)
2、之前介紹過一個在命令列將圖片轉換為 ascii 字元檢視的工具
aview/asciiview,不過它是黑白的。現在,這裡是個彩色的:
$
$
$
$
7 of 8
sudo apt-get install caca-utils
cacaview <pic_file>
cacademo
cacafire
08/17/2015 07:43 PM資料流重定向 - 實驗樓
https://www.shiyanlou.com/courses/document/346
動手做實驗,輕鬆學IT。
實驗樓-通過動手實踐的方式學會IT技術。
公司簡介 (/aboutus) 聯絡我們 (/contact) 常見問題 (/faq#howtostart) 加入我們 (/hire) 隱私協議 (/privacy)
會員條款 (/terms)
站長統計 (http://www.cnzz.com/stat/website.php?web_id=5902315)
蜀ICP備13019762號 (http://www.miibeian.gov.cn/)
(http://www.anquan.org/authenticate/cert/?site=www.shiyanlou.com&at=realname)
QQ群
微信
微博
(http://weibo.com/shiyanlou2013)
8 of 8
08/17/2015 07:43 PM

相關文章