輸入輸出重新導向


操作範例

[輸入輸出重新導向]

  1. 把從鍵盤敲進去的文字以列為單位, 排列後輸出到螢幕上: sort (不會有提示符號出現; 盡管輸入資料就對了. 記得按 ^d 表示資料輸入完畢)
  2. 令 shell 安排, 製造「使用者將檔案 ~/COPYING 的內容從鍵盤上敲進去」的假像, 讓 sort 以為還是從鍵盤上讀到資料, 排列後輸出到螢幕上: sort < ~/COPYING
  3. 令 shell 安排, 讓命令以為還是把輸出寫到螢幕上, 但其實它的輸出都被 shell 收集起來, 放到 ~/abc 這個檔案去了: sort > ~/abc 再檢查一下新檔案的內容: less -ri ~/abc
  4. 同時使用 input redirection 與 output redirection: sort < ~/COPYING > xyz 再檢查一下新檔案的內容: less -ri ~/xyz
  5. 把命令輸出的結果附加到原有的檔案後面, 而不要覆蓋掉原有的資料: sort ~/COPYING >> xyz
  6. 看一下描述系統內所有套件的摘要: rpm -qai 但內容太多了, 只能看到後面. 所以我們用 output redirection 把它的輸出存到檔案裡去: rpm -qai > ~/a 注意圖: rpm 並未從 stdin 讀資料.
  7. 接下來用 grep 尋找特定字串 (把含有指定字串的那些列整列印出來) 先從鍵盤輸入資料試試看 grep 的效果: grep Summary 然後再真的從剛才建立的檔案讀資料 grep Summary < ~/a
  8. 用 pipe 把上面兩個命令串起來, 省略中間的暫存檔, 一氣呵成: rpm -qai | grep Summary
  9. 用 wc 數數看 rpm -qai 產生出多少資料 (字元數, 字數, 列數): rpm -qai | wc 而經過 grep 處理之後又剩下多少資料: rpm -qai | grep Summary | wc
  10. Q: 如果單獨下 wc 命令會發生什麼事?
  11. 想知道系統內安裝了那些與 graph 相關的套件, 而且希望不需要產生臨時檔就可以直接用 less 來看印出來的結果: rpm -qai | grep Summary | grep -i graph | less [一個命令列上用了三個水管]
  12. 目前目錄下有那幾個檔案是 perl 程式呢? file * | grep perl 注意: 圖該怎麼畫? file 命令有沒有從 stdin 讀資料?

名詞解釋

  1. input redirection 輸入重新導向: 令 shell 安排, 在一個命令不知情的情況下, 把某個檔案的內容餵給這個命令吃, 而這個命令還以為資料是使用者從鍵盤上敲進去的. 這樣子, 每個撰寫命令的程式設計師都可以不必花心思處理檔案/目錄/..., 只要會處理鍵盤的輸入就可以了; 而使用者不需要修改程式, 可以在 使用 的時候決定輸入資料到底要從鍵盤上敲進去, 還是要從某個原先就準備好的檔案讀出來.
  2. output redirection 輸出重新導向: 令 shell 安排, 讓一個命令以為還是把輸出寫到螢幕上, 但其實它的輸出都被 shell 收集起來, 放到使用者指名的檔案去了. 這樣子, 每個撰寫命令的程式設計師都可以不必花心思處理檔案/目錄/..., 只要會處理螢幕的輸入就可以了; 而使用者則不需要修改程式, 可以在 使用 的時候決定輸出資料到底要印到螢幕上, 還是要存到某個檔案去.
  3. standard input (stdin) 標準輸入裝置: 就是鍵盤啦, 其實也算是一個檔案!
  4. standard output (stdout) 標準輸出裝置: 就是螢幕啦, 其實也算是一個檔案!
  5. standard error (stderr) 標準錯誤裝置: 應用程式印出錯誤訊息的地方, 通常也就是螢幕啦, 其實也算是一個檔案!
  6. filter: 凡是主要資料從 stdin 讀入, 將結果輸出到 stdout 的這類程式, 都叫做 filter. 例如 sort, grep, wc 都是 filters. Filter 類命令都沒有 prompt, 而且平常也不是以 interactive 的方式來使用的.
  7. pager (分頁閱讀器?): 像是 less 或 more 這類的程式, 為了方便使用者閱讀很長的資料, 讓使用者可以一次看一頁 (而不會一下子全部上捲不見), 甚至可以上下捲動畫面, 叫做一個 pager. 一般的 pager 可以從檔案讀資料, 也可以接在 pipe 後面, 假裝從 stdin 讀資料. Pager 類程式自己去控制螢幕上的遊標, 反白, 捲動等等, 已不把螢幕當一個靜態的檔案看待, 不能算是輸出到 stdout, 所以不算是 filter.
  8. pipe ("用水管連接命令"): 令 shell 安排, 讓前一個命令本來要輸出到 stdout 的資料轉向流入水管, 同時讓後面的命令本來要從 stdin 讀入的資料轉而自水管取得. (當然如果前一個命令本來就沒有要輸出到 stdout 去, 那麼就不會有資料流入水管內; 如果後面的命令本來就沒有要從 stdin 讀入資料, 那麼從水管內流出的資料就會消失了. 這都是錯誤的使用法.) 一個命令列上可以用好幾個 pipes 把許多命令串起來使用, 當然 filter 類命令可以放在 pipe 的上中下游; 而 pager 類命令只能放在 pipe 的管線末端.
  9. 其實很多命令既可以從 stdin 讀, 也可以 (自發地) 從檔案讀, 甚至可以將 stdin 與檔案的資料串在一起, 一併處理 (通常用 - 代表 stdin). 詳見 sort, grep, cat 等命令的手冊.

作業

  1. 用 last 命令檢查月初以來 penguin 的使用狀況, 用 cut 取出使用者代號, 用 sort 按照使用者代號排序, 用 uniq 統計每個使用者的上機次數, 再用 sort 按照上機次數多寡排序, 最後用 less 觀看結果. 先用臨時檔一步一步實驗, 最後用 pipe 一氣呵成, 並畫圖解釋.