資料流重定向

2021-07-11 13:39:06 字數 3817 閱讀 6591

重定向,將原本輸出到標準輸出的資料重定向到乙個檔案中,因為標準輸出(/dev/stdout)本身也是乙個檔案,我們將命令輸出導向另乙個檔案自然也是沒有任何問題的。

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

$ echo 'hello shiyanlou' > redirect 

$ echo 'www.jly.com' >> redirect

$ cat redirect

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

在更多了解 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 <#include

int main()

eof

將乙個檔案作為命令的輸入,標準輸出作為命令的輸出

$ cat documents/test.c
將echo命令通過管道傳過來的資料作為cat命令的輸入,將標準輸出作為命令的輸出

$ echo

'hi' | cat

將echo命令的輸出從預設的標準輸出重定向到乙個普通檔案

$ echo

'hello jly> redirect

$ cat redirect

要注意不要將管道和重定向混淆,管道預設是連線前乙個命令的輸出到下乙個命令的輸入,而重定向通常是需要乙個檔案來建立兩個命令的連線,可以仔細體會一下上述第三個操作和最後兩個操作的異同點。

重定向標準輸出到檔案,這是乙個很實用的操作,另乙個很實用的操作是將標準錯誤重定向,標準輸出和標準錯誤都被指向偽終端的螢幕顯示,所以我們經常看到的乙個命令的輸出通常是同時包含了標準輸出和標準錯誤的結果的。比如下面的操作:

# 使用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的檔案中

經常可能還有這樣的需求,除了將需要將輸出重定向到檔案之外也需要將資訊列印在終端,那麼可以使用tee命令來實現:

$ echo

'hello shiyanlou' | tee hello

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

# 先開啟乙個子 shell

$ zsh

# 使用exec替換當前程序的重定向,將標準輸出重定向到乙個檔案

$ exec 1>somefile

# 後面你執行的命令的輸出都將被重定向到檔案中,直到你退出當前子shell,或取消exec的重定向(後面將告訴你怎麼做)

$ ls

$ exit

$ cat somefile

預設在 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

如上面我們開啟的3號檔案描述符,可以使用如下操作將它關閉:

$ exec

3>&-

$ cd /dev/fd;ls -al;cd -

在 linux 中有乙個被成為「黑洞」的裝置檔案,所以匯入它的資料都將被「吞噬」。

在類 unix 系統中,/dev/null,或稱空裝置,是乙個特殊的裝置檔案,它通常被用於丟棄不需要的輸出流,或作為用於輸入流的空檔案,這些操作通常由重定向完成。讀取它則會立即得到乙個eof。

我們可以利用設個/dev/null遮蔽命令的輸出:

$ cat documents/test.c nefile 1>/dev/null

2>&1

xargs 是一條 unix 和類 unix 作業系統的常用命令。它的作用是將引數列表轉換成小塊分段傳遞給其他命令,以避免引數列表過長的問題。

這個命令在有些時候十分有用,特別是當用來處理產生大量輸出結果的命令如 find,locate 和 grep 的結果,詳細用法請參看 man 文件。

$ cut -d: -f1 < /etc/passwd | sort | xargs echo
上面這個命令用於將/etc/passwd檔案按:分割取第乙個字段排序後,使用echo命令生成乙個列表。

資料流重定向

管道預設是連線前乙個命令的輸出到下乙個命令的輸入 linux中提供三個標準輸入與輸出 檔案路徑 檔案作用 dev stdin 用於標準輸入 dev stdout 用於標準輸出 dev stderr 用於錯誤輸出 簡單的重定向 通過管道把檔案的輸出作為cat的輸出,並把cat的輸出作為檔案test的輸...

資料流重定向

linux在你登入時,便將預設的標準輸入 標準輸出 標準錯誤輸出安排成你的終端。i o重定向就是你通過與終端互動,或者在shell script裡設定,重新安排從 輸入或者輸出到 每個程式都應該有標準輸入 輸出 錯誤輸出 重定向的方法大抵有 管道等 先了解stdin stdout stderr。標準...

資料流重定向

linux在你登入時,便將預設的標準輸入 標準輸出 標準錯誤輸出安排成你的終端。i o重定向就是你通過與終端互動,或者在shell script裡設定,重新安排從 輸入或者輸出到 每個程式都應該有標準輸入 輸出 錯誤輸出 重定向的方法大抵有 管道等 先了解stdin stdout stderr。標準...