RHCE 5.x 筆記 - RH033 Unit7 Standard Input Output and Pipes

Standard Input and Output

以下為常用的 Standard Input and Output 數值 (實際上不只此三個數值而以,而是 0 ~ 10)。
  • 0: Standard input (STDIN) 預設為鍵盤輸入值。
  • 1: Standard output (STDOUT) 預設為終端機螢幕顯示。
  • 2: Standard error (STDERR) 預設為終端機螢幕顯示。

Redirecting Output to a File

以下為常用的 Redirecting Output 符號。
  • >: Overwrite (預設等於 1>)。
  • &>: Redirect all output (1 ~ 10)。
  • 2>&1: Redirect STDERR to STDOUT。
  • >>: Append。
  • |: Pipe。
  • <: Redirect-Input。
  • <<: End-Word。

例如下列操作中輸入的指令 ls /tmp 即為 Standard Input (0) 而查詢結果即為 Standard Output (1)
ls /tmp/        //Standard Input (0)
 mapping-root     //Standard Output (1)

接下來請使用一般使用者帳號 weithenn 來登入系統進行練習,如下操作完成後相信您會更了解何為 Standard Input、Standard Output、Standard Error。

下列操作中即為同時產生了 Standard Input、Standard Output、Standard Error 的結果。
 $ find /etc -iname passwd   //Standard Input (0)
 find: /etc/racoon/certs: Permission denied   //Standard Error (2)
 find: /etc/cups/ssl: Permission denied       //Standard Error (2)
 find: /etc/audisp: Permission denied         //Standard Error (2)
 find: /etc/selinux/targeted/modules/previous: Permission denied  //Standard Error (2)
 find: /etc/selinux/targeted/modules/active: Permission denied    //Standard Error (2)
 /etc/pam.d/passwd                            //Standard Output (1)
 /etc/passwd                                  //Standard Output (1)
 find: /etc/lvm/backup: Permission denied     //Standard Error (2)
 find: /etc/lvm/archive: Permission denied    //Standard Error (2)
 find: /etc/lvm/cache: Permission denied      //Standard Error (2)
 find: /etc/audit: Permission denied          //Standard Error (2)
 find: /etc/cron.d: Permission denied         //Standard Error (2)
 find: /etc/pki/CA: Permission denied         //Standard Error (2)

您也可配合使用 Redirect 符號將您想要得到結果輸出至指定檔案中,如下操作中將 find 搜尋結果 Redirect 至檔案 find.out 中而使用的 Redirect 符號為 > (等於 1>) 也就是將 Standard output (1) 結果輸出至檔案 find.out 中,所以您可看到指定執行後畫面只輸出 Standard Error (2) 的結果。
 $ find /etc -name passwd > find.out  //Standard Input (0)
 find: /etc/racoon/certs: Permission denied   //Standard Error (2)
 find: /etc/cups/ssl: Permission denied
 find: /etc/audisp: Permission denied
 find: /etc/selinux/targeted/modules/previous: Permission denied
 find: /etc/selinux/targeted/modules/active: Permission denied
 find: /etc/lvm/backup: Permission denied
 find: /etc/lvm/archive: Permission denied
 find: /etc/lvm/cache: Permission denied
 find: /etc/audit: Permission denied
 find: /etc/cron.d: Permission denied
 find: /etc/pki/CA: Permission denied
 $ cat find.out     //查看 find.out 檔案內容
 /etc/pam.d/passwd  //剛才指令 Standard Output (1) 的結果
 /etc/passwd

所以若您將 Redirect 符號改變為 2> 也就是將輸出結果為 Standard Error (2) 內容導入至檔案 find.out 中,那麼螢幕上顯示則僅剩 Standard Output (1)。
 $ find /etc -name passwd 2> find.out  //Standard Input (0)
 /etc/pam.d/passwd                    //Standard Output (1)
 /etc/passwd
 $ cat find.out   //查看 find.out 檔案內容
 find: /etc/racoon/certs: Permission denied  //剛才指令 Standard Error (2) 的結果
 find: /etc/cups/ssl: Permission denied
 find: /etc/audisp: Permission denied
 find: /etc/selinux/targeted/modules/previous: Permission denied
 find: /etc/selinux/targeted/modules/active: Permission denied
 find: /etc/lvm/backup: Permission denied
 find: /etc/lvm/archive: Permission denied
 find: /etc/lvm/cache: Permission denied
 find: /etc/audit: Permission denied
 find: /etc/cron.d: Permission denied
 find: /etc/pki/CA: Permission denied

當然您也可利用多個 Argument 來達成將 Standard Output (1) 及 Standard Error (2) 結果導至不同的檔案。
 $ find /etc -name passwd > find.out 2> find.err
若您不想寫那麼多的話您可利用 2>&1 來達成,不過在使用上要注意其位置,否則可能輸出的結果不是您想要的結果,如下為將 find 指令執行結果 Standard Output (1) 輸出至檔案 find.out 中在透過 2>&1 符號 Redirect STDERR to STDOUT 所以在 find.out 中內容為 Standard Output (1) 及 Standard Error (2)。
 $ find /etc -name passwd > find.out 2>&1
將 find 指令執行結果 Standard Error (2) 顯示至終端 (螢幕) 而將 Standard Output (1) 結果 Redirect 至檔案 find.out 中。
 $ find /etc -name passwd 2>&1 > find.out
 find: /etc/racoon/certs: Permission denied
 find: /etc/cups/ssl: Permission denied
 find: /etc/audisp: Permission denied
 find: /etc/selinux/targeted/modules/previous: Permission denied
 find: /etc/selinux/targeted/modules/active: Permission denied
 find: /etc/lvm/backup: Permission denied
 find: /etc/lvm/archive: Permission denied
 find: /etc/lvm/cache: Permission denied
 find: /etc/audit: Permission denied
 find: /etc/cron.d: Permission denied
 find: /etc/pki/CA: Permission denied


Redirecting STDOUT to a Program (Piping)

我們可利用管線 (|) Pipe 來使上個指令的輸出結果變成為下個指令的輸入,如下指令配合 Pipe 應該可輕鬆顯示目前網路卡上的 IP Address。
ifconfig | grep Bc | cut -f2 -d: | cut -f1 -d" "
 192.168.1.10

也可使用 Pipe 來達成將 Mail 內容快速輸入的效果。

Mail 寄送
方式一、將檔案內容直接轉換為郵件內容
ex. mail -s "test1" weithenn < /etc/s*/n*s/ifcfg-eth0
方式二、透過 echo 及 Pipe 將簡單字串輸入至郵件內容中
ex. echo "Test Mail 2" | mail -s "test2" weithenn
方式三、利用互動模式手動輸入郵件內容
ex. mail -s "test3" weithenn    //輸入後按下 Enter
 Test Mail 3                       //郵件內容
 .                                 //表示郵件內容結束

Mail 收取
  • 指令 mail 讀取系統郵件,常用操作如下。
  • >number: 讀取指定郵件 (每封郵件前皆有數字)。
  • >x: 離開,但郵件留在 MailBox 中 (下次進入還會看到讀取過的 Mail)。
  • >g: 離開,讀取過的郵件將轉移至 ~/mbox 中。
  • >h: 顯示所有信件。

Redirecting to Multiple Targets (tee)

tee 指令可以配合 Pipe 指令在輸出 Pipe 執行途中其結果方便您除錯,如下操作中利用 tee 指令將上一個 Pipe (grep Bc) 輸出內容導入 my.nic 檔案中,因此若 Pipe 指令出錯時可利用 tee 來進行除錯。
ifconfig | grep Bc | tee my.nic | cut -f2 -d: | cut -f1 -d" "
 192.168.1.10
cat my.nic
 inet addr:192.168.1.10  Bcast:10.10.25.255  Mask:255.255.255.0


Redirecting STDIN from a File (tr)

tr 指令可將指定檔案中其英文字元內容進行 大/小寫變換,如下操作將家目錄下 .bash_profile 檔案內容中所有英文大寫字母變更為小寫英文字母 (僅輸出至螢幕而非改變實際檔案內容)。
tr 'A-Z' 'a-z' < ~/.bash_profile
 # .bash_profile
 # get the aliases and functions
 if [ -f ~/.bashrc ]; then
         . ~/.bashrc
 fi
 # user specific environment and startup programs
 path=$path:$home/bin
 export path
 unset username


Scripting for loops continued

我們可於 for 迴圈中透過 seq 來輕鬆輸出數字,並可透過 -w 參數來將對齊。下列為 for 迴圈中初始值為 1、間值為 1 (每次加 1)、結束值 10,利用 echo 來輸出每次利用 seq 指定的 i 值。
for i in $(seq 1 1 10); do echo ${i}; done
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

透過 -w 參數來對齊數字。
for i in $(seq -w 1 1 10); do echo ${i}; done
 01
 02
 03
 04
 05
 06
 07
 08
 09
 10

下列為 for 迴圈中初始值為 1、間值為 3 (每次加 3)、結束值 10,利用 echo 來輸出每次利用 seq 指定的 i 值並透過 -w 參數來對齊數字。
for i in $(seq -w 1 3 10); do echo ${i}; done
 01
 04
 07
 10

下列為 for 迴圈中初始值為 2、間值為 2 (每次加 2)、結束值 20,利用 echo 來輸出每次利用 seq 指定的 i 值並透過 -w 參數來對齊數字。
for i in $(seq -w 2 2 20); do echo ${i}; done
 02
 04
 06
 08
 10
 12
 14
 16
 18
 20