(十三)數據流重定向

一、實驗介紹

1.1 實驗內容

你可能對重定向這個概念感到些許陌生,但你應該在前面的課程中多次見過>
或>>
操作了,并知道他們分別是將標準輸出導向一個文件或追加到一個文件中。這其實就是重定向,將原本輸出到標準輸出的數據重定向到一個文件中,因為標準輸出(/dev/stdout
)本身也是一個文件,我們將命令輸出導向另一個文件自然也是沒有任何問題的。
1.2 實驗知識點
重定向怎么用
文件描述符(0,1,2)

二、數據流重定向
下面我們簡單的回顧一下我們前面經常用到的兩個重定向操作:

echo 'hello shiyanlou' > redirect echo 'www.shiyanlou.com' >> redirect$ cat redirect

當然前面沒有用到的<和<<操作也是沒有問題的,如你理解的一樣,它們的區別在于重定向的方向不一致而已,>表示是從左到右,<右到左。

2.1 簡單的重定向
在更多了解 Linux 的重定向之前,我們需要先知道一些基本的東西,前面我們已經提到過 Linux 默認提供了三個特殊設備,用于終端的顯示和輸出,分別為stdin(標準輸入,對應于你在終端的輸入),stdout(標準輸出,對應于終端的輸出),stderr(標準錯誤輸出,對應于終端的輸出)。

文件描述符 設備文件 說明
0 /dev/stdin 標準輸入
1 /dev/stdout 標準輸出
2 /dev/stderr 標準錯誤

文件描述符:文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核為每一個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫往往會圍繞著文件描述符展開。但是文件描述符這一概念往往只適用于 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.2 標準錯誤重定向
重定向標準輸出到文件,這是一個很實用的操作,另一個很實用的操作是將標準錯誤重定向,標準輸出和標準錯誤都被指向偽終端的屏幕顯示,所以我們經??吹降囊粋€命令的輸出通常是同時包含了標準輸出和標準錯誤的結果的。比如下面的操作:

使用cat 命令同時讀取兩個文件,其中一個存在,另一個不存在cat Documents/test.c hello.c# 你可以看到除了正確輸出了前一個文件的內容,還在末尾出現了一條錯誤信息# 下面我們將輸出重定向到一個文件,根據我們前面的經驗,這里將在看不到任何輸出了 cat Documents/test.c hello.c > somefile


遺憾的是,這里依然出現了那條錯誤信息,這正是因為如我上面說的那樣,標準輸出和標準錯誤雖然都指向終端屏幕,實際它們并不一樣。那有的時候我們就是要可以隱藏某些錯誤或者警告,那又該怎么做呢。這就需要用到我們前面講的文件描述符了:

將標準錯誤重定向到標準輸出,再將標準輸出重定向到文件,注意要將重定向到文件寫到前面cat Documents/test.c hello.c >somefile 2>&1# 或者只用bash提供的特殊的重定向符號"&"將標準錯誤和標準輸出同時重定向到文件 cat Documents/test.c hello.c &>somefilehell

注意你應該在輸出重定向文件描述符前加上&
,否則shell會當做重定向到一個文件名為1的文件中


2.3 使用tee
命令同時重定向到多個文件
你可能還有這樣的需求,除了需要將輸出重定向到文件,也需要將信息打印在終端。那么你可以使用tee
命令來實現:
$ echo 'hello shiyanlou' | tee hello


2.4 永久重定向
你應該可以看出我們前面的重定向操作都只是臨時性的,即只對當前命令有效,那如何做到“永久”有效呢,比如在一個腳本中,你需要某一部分的命令的輸出全部進行重定向,難道要讓你在每個命令上面加上臨時重定向的操作嘛,當然不需要,我們可以使用exec
命令實現“永久”重定向。exec
命令的作用是使用指定的命令替換當前的 Shell,及使用一個進程替換當前進程,或者指定新的重定向:

先開啟一個子 Shellzsh# 使用exec替換當前進程的重定向,將標準輸出重定向到一個文件 exec 1>somefile# 后面你執行的命令的輸出都將被重定向到文件中,直到你退出當前子shell,或取消exec的重定向(后面將告訴你怎么做)ls exit$ cat somefile


2.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" >&3cat somefile exit


2.6 關閉文件描述符
如上面我們打開的3號文件描述符,可以使用如下操作將它關閉:
exec 3>&-
cd /dev/fd;ls -Al;cd -

2.7 完全屏蔽命令的輸出
在 Linux 中有一個被稱為“黑洞”的設備文件,所以導入它的數據都將被“吞噬”。
在類 UNIX 系統中,/dev/null,或稱空設備,是一個特殊的設備文件,它通常被用于丟棄不需要的輸出流,或作為用于輸入流的空文件,這些操作通常由重定向完成。讀取它則會立即得到一個EOF。

我們可以利用設個/dev/null
屏蔽命令的輸出:
$ cat Documents/test.c nefile 1>/dev/null 2>&1

上面這樣的操作將使你得不到任何輸出結果。
2.8 使用 xargs 分割參數列表
xargs 是一條 UNIX 和類 UNIX 操作系統的常用命令。它的作用是將參數列表轉換成小塊分段傳遞給其他命令,以避免參數列表過長的問題。

這個命令在有些時候十分有用,特別是當用來處理產生大量輸出結果的命令如 find,locate 和 grep 的結果,詳細用法請參看 man 文檔。
$ cut -d: -f1 < /etc/passwd | sort | xargs echo

上面這個命令用于將/etc/passwd
文件按:
分割取第一個字段排序后,使用echo
命令生成一個列表。
輕松一下
之前介紹過一個在命令行將圖片轉換為 ascii 字符查看的工具 aview/asciiview,不過它是黑白的?,F在,這里是個彩色的:
sudo apt-get install caca-utils cacaview <pic_file>cacademo cacafire


三、作業
1、理解下面這段代碼的的作用,實際這段代碼不會正常工作,請結合這一小節的知識分析這段代碼沒有正確工作的原因,并設法解決這個問題。
如果你還沒有 Shell 腳本編程的基礎,你可以選擇跳過或者到這里高級 Bash 編程指南學習

while read filename; do rm -iv $filenamedone <<(ls)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,237評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,957評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 177,248評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,356評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,081評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,485評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,534評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,720評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,263評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,025評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,204評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,787評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,461評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,874評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,105評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,945評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,205評論 2 375

推薦閱讀更多精彩內容