4. shell基本特性之~ 重定向

第 3 章目錄:

3.1 shell 語法
3.2 shell 命令
3.3 shell 函數
3.4 shell 參數
3.5 shell 展開
3.6 重定向
3.7 命令執行
3.8 shell 腳本

本文件內容為 "3.6 重定向"


對于一條命令而言,我們關心的是命令的輸入,以及命令的輸出。命令的輸出有兩種,一是標準輸出,一是命令的錯誤信息輸出。默認情況下,命令的標準輸出寫入到“標準輸出文件”,其文件描述符為1。標準輸出文件是一個特殊的文件,其中的內容是直接展示到屏幕上的。命令的錯誤輸出默認也是寫入“標準輸出文件”。命令的標準輸入,默認從“標準輸入文件”中讀取內容,其文件描述符為 0。標準輸入文件直接與我們的鍵盤輸入設備關聯。

舉例來講,比如我們執行 ls 命令,在屏幕上直接會顯示當前目錄的內容:

[root@vm2 zabbix]# ls
zabbix_agentd.log

這就是因為 ls 命令的標準輸出是寫入到“標準輸出文件”中,因為“標準輸出文件”很特殊,它的內容會直接展示到屏幕上,所以我們執行 ls 命令才能直接看到類似上面的輸出。

對于命令的標準輸入來講,比如,執行 cat - 命令,cat 命令會直接顯示指定文件的內容(把指定文件內容寫到“標準輸出文件”),cat - 表示顯示“標準輸入文件”的內容,這時就會等待我們從鍵盤輸入,這里隨意輸入一個字符串,按回車之后便顯示出來了:

[guli@gulideMacBook-Air ~]$ cat -
alskdf
alskdf

而我們要做重定向,其實就是改變默認的設定,將命令的輸入和輸出與其他文件關聯。

如果對命令做了重定向,在命令執行之前,命令的輸入輸出可被重定向。

重定向也可用于為當前的 shell 環境打開文件或關閉文件。

重定向符號的位置:重定向符號可出現在一個簡單命令的之前,之中和之后。

重定向按照出現的順序,從左至右執行。

在重定向符號之前可跟一個文件描述符,比如 2>;也可跟 {VARNAME}。

如果是 {VARNAME},對于除了 '>&-' 和 '<$-' 之外的所有重定向符號,一個大于 10 的文件描述符將被分配給 {VARNAME}。

對于 '>&-' 和 '<$-',VARNAME 的值定義了一個文件描述符,其關聯的文件將被關閉。

在下面的描述中,如果沒有顯式地寫出文件描述符,那么:
第一個重定向符號為 '<' 時,表示 標準輸入 文件(文件描述符為 0)。
第一個重定向符號為 '>' 時,表示 標準輸出 文件(文件描述符為 1)。

跟在重定向符號之后的單詞,除非另有說明,可進行如下展開:
花括號展開,波浪線展開,參數展開,命令替換,算術展開,引用取消,文件名展開 以及 單詞分割。

如果展開為多個單詞,bash 會報告一個錯誤。

注意,重定向的順序是很重要的。比如:

ls > DIRLIST 2>&1

表示先對 “標準輸出”(文件描述符為1)做重定向,文件描述符1 被關聯到 DIRLIST 文件。

然后對 “標準錯誤輸出”(文件描述符為 2)做重定向,這里使用了一個引用 &1,表示與文件描述符1關聯的文件,因為已經做了重定向,其值為 DIRLIST,于是標準錯誤輸出被重定向到了 DIRLIST 文件。

最終效果是同時對將 標準輸出 和 標準錯誤輸出(文件描述符為 2) 導入到 DIRLIST 文件。

 ls 2>&1 > DIRLIST

對比上一條,這條命令只把標準輸出導入文件 DIRLIST。

2>&1 表示對標準錯誤輸出做重定向,也就是準備改變文件描述符 2 所關聯的文件。這里重定向到文件描述符 1 關聯的文件,關聯的文件仍然是默認的 “標準輸出文件”。

> 表示對標準輸出做重定向,也就是改變文件描述符 1 所關聯的文件,這里被重定向到了 DIRLIST。

bash 在做重定向時,對一些文件名進行特殊對待:

'/dev/fd/FD'
如果 FD 是有效的整數,文件描述符 FD 被復制。

'/dev/stdin'
文件描述符 0 被復制。

'/dev/stdout'
文件描述符 1 被復制。

'/dev/stderr'
文件描述符 2 被復制。

'/dev/tcp/HOST/PORT'

如果 HOST 是有效的主機名,或是 IP 地址,而且 PORT 是一個整數的端口數字,或是 服務名字,那么 bash 會嘗試打開一個 TCP 連接到對應的 socket。

'/dev/udp/HOST/PORT'

如果 HOST 是有效的主機名,或是 IP 地址,而且 PORT 是一個整數的端口數字,或是 服務名字,那么 bash 會嘗試打開一個 UDP 連接到對應的 socket。

如果打開文件失敗,或者創建文件失敗,將導致重定向失敗。

大于 9 的文件描述符應謹慎使用,因為 shell 內部可能會用到。

3.6.1 輸入重定向


以 WORD 的展開結果為文件名。輸入重定向使得以該文件名命名的文件
與文件描述符 'N' 關聯,且文件被打開并等待讀取。
如果 'N' 未指定,文件被關聯到標準輸入。

[N]<WORD

3.6.2 輸出重定向


以 WORD 的展開結果為文件名。輸入重定向使得以該文件名命名的文件與文件描述符 'N' 關聯,且文件被打開并等待寫入。如果 'N' 未指定,文件被關聯到標準輸出。

如果文件不存在,將被創建。如果文件存在,文件內容被清空(truncated)。

[N]>[|]WORD

如果重定向符號是 '>',且 'noclobber' 選項被 set 命令開啟,如果文件已存在,而且文件是普通文件,重定向會失敗。

如果重定向符號是 '>|',或者是 '>' 且 'noclobber' 未開啟,那么即使文件已經存在,也會嘗試進行重定向。

3.6.3 追加輸出重定向


追加輸出重定向,會將輸出追加到文件已有的內容之后。如果文件不存在,將被創建。

[N]>>WORD

3.6.4 重定向標準輸出和標準錯誤輸出


這個構造允許 標準輸出 和 標準錯誤輸出 同時重定向到文件。

有兩種形式:

&>WORD
>&WORD

以上兩者中,第一種更受歡迎 &>WORD。

在語義上,它們與此相同:

>WORD 2>&1

>WORD: 即 1>WORD,將WORD文件跟 “文件描述符1” 關聯,等待寫入。
       表示標準輸出重定向到WORD文件。

2>&1: 表示將 “文件描述符2” 跟 “文件描述符1” 所關聯的文件做關聯,
      等待寫入。

3.6.5 追加重定向標準輸出和標準錯誤輸出


這個構造允許 標準輸出 和 標準錯誤輸出 同時重定向到文件。
其形式為:

&>>WORD

在語義上,它與此相同:

>>WORD 2>>&1

3.6.6 Here Document


這種重定向從當前 source 讀取輸入,直到出現只包含 WORD 的行出現(其后不跟任何 blank 字符)。此前讀取的所有行,將被當做一個命令的標準輸入來使用。

<<[-]WORD
    HERE-DOCUMENT
DELIMITER

對 WORD 不會進行 參數展開,命令替換,算術展開 和 文件名展開。

如果 WORD 中包含被引用的字符,DELIMITER 等于引用刪除后的值,here-document 中的所有行不做展開。

如果 WORD 未被引用,here-document 中的所有行可進行 參數展開,命令替換 和 算術展開。'\newline' 被忽略,而且 '' 必須用來引用 '','$' 以及 '`'。

如果重定向符號是 '<<-',所有 leading tab 字符將從輸入行中刪除,包括含有 DELIMITER 的行。這允許在 shell script 中的 here-document 以自然的方式進行縮進。

3.6.7 Here String


這是 here-document 的變體:

<<< WORD

WORD 被展開,然后提供給一個命令的標準輸入。

3.6.8 文件描述符的復制


輸入文件描述符的復制:

[N]<&WORD 

這個重定向運算符被用來對輸入文件描述符做復制。

如果 WORD 展開為一個或多個數字,描述符 'N' 關聯的文件被做成展開數字(作為文件描述符)所關聯文件的一個拷貝。

如果 WORD 不是一個以讀方式打開的文件描述符,會導致重定向報錯。如果 WORD 等于 '-',描述符 'N' 被關閉。

如果 'N' 沒有指定,則使用 標準輸入(文件描述符為 0)。

輸出文件描述符的復制:

[N]>&WORD 

這個重定向運算符被用來對輸出文件描述符做復制。如果 WORD 展開為一個或多個數字,描述符 'N' 關聯的文件被做成展開數字(作為文件描述符)所關聯文件的一個拷貝。

如果 WORD 不是一個以寫方式打開的文件描述符,會導致重定向報錯。

如果 'N' 沒有指定,默認為1.

如果 'N' 沒有指定,且 WORD 沒有展開為數字,那么標準輸出和標準錯誤輸出會被重定向(如前面的小節所述)。

3.6.9 文件描述符移動


[N]<&DIGIT-

將文件描述符 DIGIT 移動到 N,如果 N 沒指定,則移動到 0。DIGIT 被復制到 N 后,DIGIT 描述符被關閉。

[N]>&DIGIT-

將文件描述符 DIGIT 移動到 N,如果 N 沒指定,則移動到 1。

3.6.10 以讀寫方式打開文件描述符


[N]<>WORD

對 WORD 進行展開,以展開結果為文件名,將該文件與描述符 'N' 關聯,以讀寫方式打開。如果 N 沒指定,使用 0 描述符。如果文件不存在則創建文件。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容