next up previous contents
Next: Shell scripts - 條件判斷與迴圈 Up: Shell Scripts - 簡介與 Previous: shell script 練習   Contents

善用判斷式

  • 利用 test 指令的測試功能
    1. 指令 test 測試的標誌
      測試的標誌 代表意義
      1. 關於某個檔名的『類型』偵測(存在與否),如 test -e filename
      -e 該『檔名』是否存在?(常用)
      -f 該『檔名』是否為檔案(file)?(常用)
      -d 該『檔名』是否為目錄(directory)?(常用)
      -b 該『檔名』是否為一個 block device 裝置?
      -c 該『檔名』是否為一個 character device 裝置?
      -S 該『檔名』是否為一個 Socket 檔案?
      -p 該『檔名』是否為一個 FIFO (pipe) 檔案?
      -L 該『檔名』是否為一個連結檔?
      2. 關於檔案的權限偵測,如 test -r filename
      -r 偵測該檔名是否具有『可讀』的屬性?
      -w 偵測該檔名是否具有『可寫』的屬性?
      -x 偵測該檔名是否具有『可執行』的屬性?
      -u 偵測該檔名是否具有『SUID』的屬性?
      -g 偵測該檔名是否具有『SGID』的屬性?
      -k 偵測該檔名是否具有『Sticky bit』的屬性?
      -s 偵測該檔名是否為『非空白檔案』?
      3. 兩個檔案之間的比較,如: test file1 -nt file2
      -nt (newer than)判斷 file1 是否比 file2 新
      -ot (older than)判斷 file1 是否比 file2 舊
      -ef 判斷 file1 與 file2 是否為同一檔案。
      4. 關於兩個整數之間的判定,例如 test n1 -eq n2
      -eq 兩數值相等 (equal)
      -ne 兩數值不等 (not equal)
      -gt n1 大於 n2 (greater than)
      -lt n1 小於 n2 (less than)
      -ge n1 大於等於 n2 (greater than or equal)
      -le n1 小於等於 n2 (less than or equal)
      5. 判定字串的資料
      test -z string 判定字串是否為 0 ?若 string 為空字串,則為 true
      test -n string 判定字串是否非為 0 ?若 string 為空字串,則為 false。
      test str1 == str2 判定 str1 是否等於 str2 ,若相等回傳 true
      test str1 != str2 判定 str1 是否不等於 str2 ,若相等回傳 false
      6. 多重條件判定,例如: test -r filename -a -x filename
      -a (and)兩狀況同時成立。例如 test -r file -a -x file,
      則 file 同時具有 r 與 x 權限時,才回傳 true。
      -o (or)兩狀況任何一個成立。例如 test -r file -o -x file,
      則 file 具有 r 或 x 權限時,就可回傳 true。
      ! 反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true
    2. 例題:檢查 /csie 是否存在:
      [root@linux ~]# test -e /csie && echo "exist" || echo "Not exist"
      
    3. 例題:讓使用者輸入一個檔名,並判斷其是否存在:
      1. 若不存在則給予一個『Filename does not exist』的訊息,並中斷程式;
      2. 若存在,則判斷是檔案或目錄,並果輸出『Filename is regular file』或『Filename is directory』;
      3. 判斷執行者對該檔案或目錄擁有的權限,並輸出權限資料。
      [root@linux scripts]# vi sh06.sh
      #!/bin/bash
      # Program:
      #       Let user input a filename, the program will search the filename
      #       1.) exist? 2.) file/directory? 3.) file permissions 
      # History:
      # 2005/08/25    csie   First release
      
      # 1. 讓使用者輸入檔名,並且判斷使用者是否真的有輸入字串?
      echo -e "The program will show you that filename
       is exist which input by you.\n\n"
      read -p "Input a filename : " filename
      test -z $filename && echo "You MUST input a filename." && exit 0
      # 2. 判斷檔案是否存在?
      test ! -e $filename && echo "The filename $filename DO NOT exist" && exit 0
      # 3. 開始判斷檔案類型與屬性
      test -f $filename && filetype="regulare file"
      test -d $filename && filetype="directory"
      test -r $filename && perm="readable"
      test -w $filename && perm="$perm writable"
      test -x $filename && perm="$perm executable"
      # 4. 開始輸出資訊
      echo "The filename: $filename is a $filetype"
      echo "And the permission are : $perm"
      

  • 利用判斷符號 [ ]
    1. 判斷變數 $HOME 是否為空的:
      [root@linux ~]# [ -z "$HOME" ]
      
    2. 在中括號 [ ] 內的每個元件都需要有空白鍵來分隔;
      # 假設空白鍵使用『□』來表示,則: 
      [  "$HOME"  ==  "$MAIL"  ]
      [□"$HOME"□==□"$MAIL"□]
       ↑       ↑  ↑       ↑
      
    3. 在中括號內,變數要以雙引號來設定;常數要以單或雙引號來設定。
      #設定 name="csie dyw" : 
      [root@linux ~]# name="csie dyw"
      [root@linux ~]# [ $name == "csie" ]
      bash: [: too many arguments
      
      # 因為 $name 沒有使用雙引號刮起來,判定式會變成: 
      [ csie dyw == "csie" ] 
      # 而不是: 
      [ "csie dyw" == "csie" ]
      
    4. 例題:使用中括號 [ ]&&|| 讓使用者選擇 Y 或 N ,
      1. 如果使用者輸入 Y 或 y 時,就顯示『 OK, continue 』
      2. 如果使用者輸入 n 或 N 時,就顯示『 Oh, interrupt 。』
      3. 如果不是 Y/y/N/n 之內的其他字元,就顯示『I don't know what is your choise』
      [root@linux scripts]# vi sh07.sh
      #!/bin/bash
      # Program:
      #       This program will show the user's choice
      # History:
      # 2005/08/25    csie   First release
      
      read -p "Please input (Y/N): " yn
      [ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
      [ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
      echo "I don't know what is your choise" && exit 0
      
  • Shell script 的預設變數 ($0, $1, ...)
    1. 變數的對應:
      /path/to/scriptname  opt1  opt2  opt3  opt4  ...
             $0             $1    $2    $3    $4   ...
      
      [root@linux ~]# /etc/init.d/crond restart
      ## $0 為 /etc/init.d/crond, $1 為 restart
      
    2. 例題:執行一個 script ,自動列出自己的檔名,後面接前三個參數:
      [root@linux scripts]# vi sh08.sh
      #!/bin/bash
      # Program:
      #       The program will show it's name and first 3 parameters.
      # History:
      # 2005/08/25    csie   First release
      
      echo "The script name is ==> $0"
      [ -n "$1" ] && echo "The 1st paramter is ==> $1" || exit 0
      [ -n "$2" ] && echo "The 2nd paramter is ==> $2" || exit 0
      [ -n "$3" ] && echo "The 3th paramter is ==> $3" || exit 0
       
      # 執行結果: 
      [root@linux scripts]# sh sh08.sh theone haha quot
      The script name is ==> sh08.sh
      The 1st paramter is ==> theone
      The 2nd paramter is ==> haha
      The 3th paramter is ==> quot
      
練習題
  1. 如何利用 test 指令檢查檔名 filename 是否存在?
    Sol. test -e filename
  2. 如何利用 test 指令檢查檔名 filename 是否為檔案?
    Sol. test -f filename
  3. 如何利用 test 指令檢查檔名 filename 是否為目錄?
    Sol. test -d filename
  4. 如何利用 test 指令檢查檔名 filename 是否為連結檔?
    Sol. test -L filename
  5. 如何利用 test 指令檢查檔名 filename 是否具有『可讀』的屬性?
    Sol. test -r filename
  6. 如何利用 test 指令檢查檔名 filename 是否具有『可寫』的屬性?
    Sol. test -w filename
  7. 如何利用 test 指令檢查檔名 filename 是否具有『可執行』的屬性?
    Sol. test -x filename
  8. 如何利用 test 指令比較檔案 file1 是否比 file2 新?
    Sol. test file1 -nt file2
  9. 如何利用 test 指令比較檔案 file1 是否比 file2 舊?
    Sol. test file1 -ot file2
  10. 如何利用 test 指令判斷 file1 與 file2 是否為同一檔案?
    Sol. test file1 -of file2
  11. 如何利用 test 指令比較兩個整數 n1 與 n2 是否相等?
    Sol. test n1 -eq n2
  12. 如何利用 test 指令比較兩個整數 n1 與 n2 是否不相等?
    Sol. test n1 -ne n2
  13. 如何利用 test 指令比較整數 n1 是否大於 n2?
    Sol. test n1 -gt n2
  14. 如何利用 test 指令比較整數 n1 是否小於 n2?
    Sol. test n1 -lt n2
  15. 如何利用 test 指令比較整數 n1 是否大於等於 n2?
    Sol. test n1 -ge n2
  16. 如何利用 test 指令判定字串 str1 是否為空字串?
    Sol. test -z str1
  17. 如何利用 test 指令判定字串 str1 是否非為空字串?
    Sol. test -n str1 或 test str1
  18. 如何利用 test 指令判定字串 str1 是否等於 str2?
    Sol. test str1 = str2
  19. 如何利用 test 指令判定字串 str1 是否不等於 str2?
    Sol. test str1 != str2
  20. 如何利用 test 指令判斷檔案 file1 是否為具有『可讀』且『可執行』的屬性?
    Sol. test -r file1 -a -x file1
  21. 如何利用 test 指令判斷檔案 file1 是否為具有『可讀』或『可執行』的屬性?
    Sol. test -r file1 -o -x file1
  22. 如何利用 test 指令判斷檔案 file1 是否為不具有『可執行』的屬性?
    Sol. test ! -x file1
  23. 如何利用判斷符號 [ ],判斷變數 $HOME 是否為空的?
    Sol. [ -z "$HOME" ]
  24. 指令 ["$HOME"=="$MAIL"],判斷變數 $HOME 是否等於變數 $MAIL,是否有錯,若有,請說明。
    Sol. 有錯,在中括號 [ ] 內的每個元件都需要有空白鍵來分隔。
  25. 指令 [ $name == "csie" ],判斷變數 $name 是否等於字串 csie,是否有錯,若有,請說明。
    Sol. 有錯,在中括號 [ ] 內的 $name 沒有使用雙引號刮起來。
  26. 執行 shell script 『sh sh07.sh theone haha quot』,則預設變數 $0, $1, $2, $3 分別為何?
    Sol. $0="sh07.sh",$1="theone",$2="haha",$3="quot"


next up previous contents
Next: Shell scripts - 條件判斷與迴圈 Up: Shell Scripts - 簡介與 Previous: shell script 練習   Contents
2017-06-14