Linux之資料流重導向

2021-08-09 02:47:12 字數 4099 閱讀 3631

其實一開始繞進檔案描述符這個大坑裡去了,越挖越深,什麼系統檔案表,記憶體索引節點,vfs等等都一下子冒了出來,而我暫時還沒那麼多精力搞定所有,於是只能遮蔽底層的一些細節,暫且當作黑盒子,來日再挖。。。

1、linux系統中,一切資源都被視為檔案,包括放在磁碟上的各種文件,甚至各種裝置。檔案是linux組織計算機硬體資源的基本邏輯單位。

2、程序,具體的說就是我們敲的所有命令,本質上就是在操作一系列檔案,接著產生一系列結果。比如常用的ls命令,後面不加引數時,操作物件預設為是當前目錄(目錄也是檔案——目錄檔案),然後把該目錄下的所有檔案的名字輸出到螢幕上(螢幕也是檔案啊衰~)。

3、操作的結果有兩種,一種是正確的結果,另一種是錯誤的結果。linux把前者稱為標準輸出,其檔案描述符是1;後者稱為標準錯誤輸出,對應的檔案描述符是2。這兩類結果資訊是分開的。預設情況下,這兩類資訊都會輸出到螢幕上,讓操作著直接、立即看到,然後閱後即焚。如果我們想把這兩類資訊儲存下來方便以後複習,就需要用到重導向了。

4、比如我的家目錄是這樣子的:

預設情況下結果直接列印到螢幕上。

那現在我想把結果儲存到file1這個檔案中,就可以這樣:

m@localhost:~$ ls > file1

ls一下,就會發現當前目錄多了乙個檔案file1:

這裡需要注意:1)如果當前目錄沒有file1檔案,那麼它就會被新建;如果已經存在乙個名叫file1的檔案,那麼之前的內容會被覆蓋。

2)> 前面如果沒有數字,則預設為1,即標準輸出。

看一下file1的內容:

這裡要注意的是,file1檔名本身也在file1的內容裡,這說明了什麼呢?對的,順序問題。

5、我們試一下這樣:

m@localhost:~$ ls program/ nothing

ls: 無法訪問nothing: 沒有那個檔案或目錄

program/:

google-chrome-stable_current_i386.rpm

顯然,把nothing作為ls的引數就會顯示錯誤,因為當前目錄下並沒有這個檔案。那麼現在把這兩個資訊分別儲存在right和wrong檔案中,就可以這樣:

m@localhost:~$ ls program/ nothing >right 2>wrong

檢查一下:

m@localhost:~$ cat right 

program/:

google-chrome-stable_current_i386.rpm

m@localhost:~$ cat wrong 

ls: 無法訪問nothing: 沒有那個檔案或目錄

6、那我想把正確資訊和錯誤資訊儲存在同一檔案中呢?可以這樣:

m@localhost:~$ ls program/ nothing &> all

檢查一下:

m@localhost:~$ cat all 

ls: 無法訪問nothing: 沒有那個檔案或目錄

program/:

google-chrome-stable_current_i386.rpm

7、還有一種方法也可以把正確資訊和錯誤資訊儲存在同一檔案中:

m@localhost:~$ ls program/ nothing > all 2>&1

解釋一下這種用法:首先,> all就是1> all,即把標準輸出重定向到all檔案中;然後2>表示把標準錯誤也重定向,但是重定向到哪兒呢?那麼&1就表示重定向到檔案描述符1所指向的那個檔案,這種用法其實類似於變數,為了方便而已。

檢查一下:

m@localhost:~$ cat all

ls: 無法訪問nothing: 沒有那個檔案或目錄

program/:

google-chrome-stable_current_i386.rpm

顯然上面的用法和這個是一樣的道理:

m@localhost:~$ ls program/ nothing 2> all 1>&2

一開始我也不明白,為什麼像這樣就不行呢?

m@localhost:~$ ls program/ nothing 2> all 1>all

多直觀多明了啊,但是是錯的。。。

m@localhost:~$ cat all

program/:

google-chrome-stable_current_i386.rpm

�錄原因嘛。。。據說是因為標準輸出和標準錯誤交替寫入all檔案時,由於沒有規定誰先誰後,於是就亂碼。而2> all 1>&2這種辦法,本質上是呼叫dup(2)這個系統函式複製了前面的行為,總之很複雜,先不管了。

8、如果這樣會怎樣?

m@localhost:~$ ls program/ nothing  1>&2 2> all

自己試試吧,還是順序問題。

這裡的&沒有固定的意思

放在>後面的&,表示重定向的目標不是乙個檔案,而是乙個檔案描述符,內建的檔案描述符如下

1 => stdout

2 => stderr

0 => stdin

換言之2>1代表將stderr重定向到當前路徑下檔名為1regular file中,而2>&1代表將stderr重定向到檔案描述符1的檔案(即/dev/stdout)中,這個檔案就是stdoutfile system中的對映

&>file是一種特殊的用法,也可以寫成>&file,二者的意思完全相同,都等價於

>file 2>&1
此處&>或者>&視作整體,分開沒有單獨的含義

第二個問題:

find /etc -name .bashrc > list

2>&1

# 我想問為什麼不能調下順序,比如這樣

find /etc -name .bashrc 2>&1 > list

這個是從左到右有順序的

第一種

*** > list

2>&1

先將要輸出到stdout的內容重定向到檔案,此時檔案list就是這個程式的stdout,再將stderr重定向到stdout,也就是檔案list

第二種

*** 2>&1 > list
先將要輸出到stderr的內容重定向到stdout,此時會產生乙個stdout的拷貝,作為程式的stderr,而程式原本要輸出到stdout的內容,依然是對接在stdout原身上的,因此第二步重定向stdout,對stdout的拷貝不產生任何影響

[@localhost test]$ ls program/ nothing > all 2>&1

[@localhost test]$ ls

all  program

[@localhost test]$ cat all

ls: 無法訪問nothing: 沒有那個檔案或目錄

program/:

ttt[@localhost test]$ ls program/ nothing  2>&1 > all

ls: 無法訪問nothing: 沒有那個檔案或目錄

[@localhost test]$

[@localhost test]$ ls

all  program

[@localhost test]$ cat all

program/:

ttt[@localhost test]$

*****====

Linux資料流重導向

當我們使用linux的時候,每下達1個命令,通常都會有對應的資訊輸出在螢幕上,這些輸出的資料就是資料流,而linux資料流重導向,就是把這些資料輸出到不同的地方了。而資料流通常分為正確的資料跟錯誤的資料,如果我們要把正確的資料導向到我們要的檔案裡面去,可以使 覆蓋 新增 來處理。malt malt ...

Linux下資料流重導向

定義 指根據命令的輸出不列印在螢幕上而是直接輸入到其他裝置比如檔案或印表機或垃圾箱 格式 命令 command option 引數 1 2 2 檔案或列印裝置 1.標準輸入 stdin 為 0 使用 或 2.標準輸出 stdout 為 1 使用 或 3.標準錯誤輸出 stderr 為 2 使用 2 ...

BASH 資料流重導向

資料流重導向 即將本應在標準輸入輸出 std input output error output 的資料傳到別的地方去。例如將除錯資訊存入文件中,而非直接輸出到螢幕上。也可以用 tee 命令,即輸出到標準輸出,又寫入指定文件 也叫雙向導向。傳送字元如下所示 1.標準輸入 stdin 為0,使用 或 ...