Linux Shell程式設計(25)——I/O 重定向

尹成發表於2014-09-30
預設情況下始終有3個"檔案"處於開啟狀態, stdin (鍵盤), stdout (螢幕), and stderr (錯誤訊息輸出到螢幕上). 這3個檔案和其他開啟的檔案都可以被重定向. 對於重定向簡單的解釋就是捕捉一個檔案, 命令, 程式, 指令碼, 或者甚至是指令碼中的程式碼塊(參見 Example 3-1 和 Example 3-2)的輸出, 然後將這些輸出作為輸入傳送到另一個檔案, 命令, 程式, 或指令碼中.


每個開啟的檔案都會被分配一個檔案描述符. stdin, stdout, 和stderr的檔案描述符分別是0, 1, 和 2. 對於正在開啟的額外檔案, 保留了描述符3到9. 在某些時候將這些格外的檔案描述符分配給stdin, stdout, 或者是stderr作為臨時的副本連結是非常有用的. 在經過複雜的重定向和重新整理之後需要把它們恢復成正常的樣子


關閉檔案描述符
n<&-關閉輸入檔案描述符n.
0<&-, <&-關閉stdin.
n>&-關閉輸出檔案描述符n.
1>&-, >&-關閉stdout.
子程式繼承了開啟的檔案描述符. 這就是為什麼管道可以工作. 如果想阻止fd被繼承, 那麼可以關掉它.

COMMAND_OUTPUT >
   # 重定向stdout到一個檔案.
   # 如果沒有這個檔案就建立, 否則就覆蓋.

   ls -lR > dir-tree.list
   # 建立一個包含目錄樹列表的檔案.

: > filename
   # > 會把檔案"filename"截斷為0長度.
   # 如果檔案不存在, 那麼就建立一個0長度的檔案(與'touch'的效果相同).
   # : 是一個佔位符, 不產生任何輸出.

> filename    
   # > 會把檔案"filename"截斷為0長度.
   # 如果檔案不存在, 那麼就建立一個0長度的檔案(與'touch'的效果相同).
   # (與上邊的": >"效果相同, 但是在某些shell下可能不能工作.)

COMMAND_OUTPUT >>
   # 重定向stdout到一個檔案.
   # 如果檔案不存在, 那麼就建立它, 如果存在, 那麼就追加到檔案後邊.

   # 單行重定向命令(只會影響它們所在的行):

1>filename
   # 重定向stdout到檔案"filename".
1>>filename
   # 重定向並追加stdout到檔案"filename".
2>filename
   # 重定向stderr到檔案"filename".
2>>filename
   # 重定向並追加stderr到檔案"filename".
&>filename
   # 將stdout和stderr都重定向到檔案"filename".

   # 重定向stdout, 一次一行.
   LOGFILE=script.log


   echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE
   echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE
   echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE
   echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"."
   # 每行過後, 這些重定向命令會自動"reset".

   # 重定向stderr, 一次一行.
   ERRORFILE=script.errors

   bad_command1 2>$ERRORFILE       #  錯誤訊息發到$ERRORFILE中.
   bad_command2 2>>$ERRORFILE      #  錯誤訊息新增到$ERRORFILE中.
   bad_command3                    #  錯誤訊息echo到stderr,
                                   #+ 並且不出現在$ERRORFILE中.
   # 每行過後, 這些重定向命令也會自動"reset".
   #==============================================================================


2>&1
   # 重定向stderr到stdout.
   # 得到的錯誤訊息與stdout一樣, 傳送到一個地方.

i>&j
   # 重定向檔案描述符i 到 j.
   # 指向i檔案的所有輸出都傳送到j中去.

>&j
   # 預設的, 重定向檔案描述符1(stdout)到 j.
   # 所有傳遞到stdout的輸出都送到j中去.

0< FILENAME
 < FILENAME
   # 從檔案中接受輸入.
   # 與">"是成對命令, 並且通常都是結合使用.
   #
   # grep search-word <filename

[j]<>filename
   # 為了讀寫"filename", 把檔案"filename"開啟, 並且分配檔案描述符"j"給它.
   # 如果檔案"filename"不存在, 那麼就建立它.
   # 如果檔案描述符"j"沒指定, 那預設是fd 0, stdin.
   #
   # 這種應用通常是為了寫到一個檔案中指定的地方.
   echo 1234567890 > File    # 寫字串到"File".
   exec 3<> File             # 開啟"File"並且給它分配fd 3.
   read -n 4 <&3             # 只讀4個字元.
   echo -n . >&3             # 寫一個小數點.
   exec 3>&-                 # 關閉fd 3.
   cat File                  # ==> 1234.67890
   # 隨機儲存.

|
   # 管道.
   # 通用目的的處理和命令鏈工具.
   # 與">"很相似, 但是實際上更通用.
   # 對於想將命令, 指令碼, 檔案和程式串連起來的時候很有用.
   cat *.txt | sort | uniq > result-file
   # 對所有的.txt檔案的輸出進行排序, 並且刪除重複行,
   # 最後將結果儲存到"result-file"中.


相關文章