輸入輸出重新導向
操作範例
- 把從鍵盤敲進去的文字以列為單位, 排列後輸出到螢幕上:
sort
(不會有提示符號出現; 盡管輸入資料就對了. 記得按 ^d 表示資料輸入完畢) - 令 shell 安排, 製造「使用者將檔案 ~/COPYING
的內容從鍵盤上敲進去」的假像, 讓 sort 以為還是從鍵盤上讀到資料,
排列後輸出到螢幕上:
sort < ~/COPYING
- 令 shell 安排, 讓命令以為還是把輸出寫到螢幕上,
但其實它的輸出都被 shell 收集起來, 放到 ~/abc 這個檔案去了:
sort > ~/abc
再檢查一下新檔案的內容:less -ri ~/abc
- 同時使用 input redirection 與 output redirection:
sort < ~/COPYING > xyz
再檢查一下新檔案的內容:less -ri ~/xyz
- 把命令輸出的結果附加到原有的檔案後面, 而不要覆蓋掉原有的資料:
sort ~/COPYING >> xyz
- 看一下描述系統內所有套件的摘要:
rpm -qai
但內容太多了, 只能看到後面. 所以我們用 output redirection 把它的輸出存到檔案裡去:rpm -qai > ~/a
注意圖: rpm 並未從 stdin 讀資料. - 接下來用 grep 尋找特定字串 (把含有指定字串的那些列整列印出來)
先從鍵盤輸入資料試試看 grep 的效果:
grep Summary
然後再真的從剛才建立的檔案讀資料grep Summary < ~/a
- 用 pipe 把上面兩個命令串起來, 省略中間的暫存檔, 一氣呵成:
rpm -qai | grep Summary
- 用 wc 數數看 rpm -qai 產生出多少資料 (字元數, 字數, 列數):
rpm -qai | wc
而經過 grep 處理之後又剩下多少資料:rpm -qai | grep Summary | wc
- Q: 如果單獨下 wc 命令會發生什麼事?
- 想知道系統內安裝了那些與 graph 相關的套件,
而且希望不需要產生臨時檔就可以直接用 less 來看印出來的結果:
rpm -qai | grep Summary | grep -i graph | less
- 目前目錄下有那幾個檔案是 perl 程式呢?
file * | grep perl
注意: 圖該怎麼畫? file 命令有沒有從 stdin 讀資料?
名詞解釋
- input redirection 輸入重新導向: 令 shell 安排, 在一個命令不知情的情況下, 把某個檔案的內容餵給這個命令吃, 而這個命令還以為資料是使用者從鍵盤上敲進去的. 這樣子, 每個撰寫命令的程式設計師都可以不必花心思處理檔案/目錄/..., 只要會處理鍵盤的輸入就可以了; 而使用者不需要修改程式, 可以在 使用 的時候決定輸入資料到底要從鍵盤上敲進去, 還是要從某個原先就準備好的檔案讀出來.
- output redirection 輸出重新導向: 令 shell 安排, 讓一個命令以為還是把輸出寫到螢幕上, 但其實它的輸出都被 shell 收集起來, 放到使用者指名的檔案去了. 這樣子, 每個撰寫命令的程式設計師都可以不必花心思處理檔案/目錄/..., 只要會處理螢幕的輸入就可以了; 而使用者則不需要修改程式, 可以在 使用 的時候決定輸出資料到底要印到螢幕上, 還是要存到某個檔案去.
- standard input (stdin) 標準輸入裝置: 就是鍵盤啦, 其實也算是一個檔案!
- standard output (stdout) 標準輸出裝置: 就是螢幕啦, 其實也算是一個檔案!
- standard error (stderr) 標準錯誤裝置: 應用程式印出錯誤訊息的地方, 通常也就是螢幕啦, 其實也算是一個檔案!
- filter: 凡是主要資料從 stdin 讀入, 將結果輸出到 stdout 的這類程式, 都叫做 filter. 例如 sort, grep, wc 都是 filters. Filter 類命令都沒有 prompt, 而且平常也不是以 interactive 的方式來使用的.
- pager (分頁閱讀器?): 像是 less 或 more 這類的程式, 為了方便使用者閱讀很長的資料, 讓使用者可以一次看一頁 (而不會一下子全部上捲不見), 甚至可以上下捲動畫面, 叫做一個 pager. 一般的 pager 可以從檔案讀資料, 也可以接在 pipe 後面, 假裝從 stdin 讀資料. Pager 類程式自己去控制螢幕上的遊標, 反白, 捲動等等, 已不把螢幕當一個靜態的檔案看待, 不能算是輸出到 stdout, 所以不算是 filter.
- pipe ("用水管連接命令"): 令 shell 安排, 讓前一個命令本來要輸出到 stdout 的資料轉向流入水管, 同時讓後面的命令本來要從 stdin 讀入的資料轉而自水管取得. (當然如果前一個命令本來就沒有要輸出到 stdout 去, 那麼就不會有資料流入水管內; 如果後面的命令本來就沒有要從 stdin 讀入資料, 那麼從水管內流出的資料就會消失了. 這都是錯誤的使用法.) 一個命令列上可以用好幾個 pipes 把許多命令串起來使用, 當然 filter 類命令可以放在 pipe 的上中下游; 而 pager 類命令只能放在 pipe 的管線末端.
- 其實很多命令既可以從 stdin 讀, 也可以 (自發地) 從檔案讀, 甚至可以將 stdin 與檔案的資料串在一起, 一併處理 (通常用 - 代表 stdin). 詳見 sort, grep, cat 等命令的手冊.
作業
- 用 last 命令檢查月初以來 penguin 的使用狀況, 用 cut 取出使用者代號, 用 sort 按照使用者代號排序, 用 uniq 統計每個使用者的上機次數, 再用 sort 按照上機次數多寡排序, 最後用 less 觀看結果. 先用臨時檔一步一步實驗, 最後用 pipe 一氣呵成, 並畫圖解釋.
- 本頁最新版網址: https://frdm.cyut.edu.tw/~ckhung/b/gnu/redirect.php; 您所看到的版本: October 30 2017 12:14:44.
- 作者: 朝陽科技大學 資訊管理系 洪朝貴
- 寶貝你我的地球, 請 減少列印, 多用背面, 丟棄時做垃圾分類。
- 本文件以 Creative Commons Attribution-ShareAlike License 或以 Free Document License 方式公開授權大眾自由複製/修改/散佈。