<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 11.4 測試與分支 `case` 和 `select` 結構并不屬于循環結構,因為它們并沒有反復執行代碼塊。但是和循環結構相似的是,它們會根據代碼塊頂部或尾部的條件控制程序流。 下面介紹兩種在代碼塊中控制程序流的方法: ### `case (in)` / `esac` 在 shell 腳本中,`case` 模擬了 C/C++ 語言中的 `switch`,可以根據條件跳轉到其中一個分支。其相當于簡寫版的 `if/then/else` 語句。很適合用來創建菜單選項喲! ```bash case "$variable" in "$condition1" ) command... ;; "$condition2" ) command... ;; esac ``` > ![note](http://tldp.org/LDP/abs/images/note.gif) > > - 對變量進行引用不是必須的,因為在這里不會進行字符分割。 > > - 條件測試語句必須以右括號 ) 結束。[^1] > > - 每一段代碼塊都必須以雙分號 ;; 結束。 > > - 如果測試條件為真,其對應的代碼塊將被執行,而后整個 `case` 代碼段結束執行。 > > - `case` 代碼段必須以 `esac` 結束(倒著拼寫case)。 樣例 11-25. 如何使用 `case` ```bash #!/bin/bash # 測試字符的種類。 echo; echo "Hit a key, then hit return." read Keypress case "$Keypress" in [[:lower:]] ) echo "Lowercase letter";; [[:upper:]] ) echo "Uppercase letter";; [0-9] ) echo "Digit";; * ) echo "Punctuation, whitespace, or other";; esac # 字符范圍可以用[方括號]表示,也可以用 POSIX 形式的[[雙方括號]]表示。 # 在這個例子的第一個版本中,用來測試是小寫還是大寫字符使用的是 [a-z] 和 [A-Z]。 # 這在一些特定的語言環境和 Linux 發行版中不起效。 # POSIX 形式具有更好的兼容性。 # 感謝 Frank Wang 指出這一點。 # 練習: # ----- # 這個腳本接受一個單字符然后結束。 # 修改腳本,使得其可以循環接受輸入,并且檢測鍵入的每一個字符,直到鍵入 "X" 為止。 # 提示:將所有東西包在 "while" 中。 exit 0 ``` 樣例 11-26. 使用 `case` 創建菜單 ```bash #!/bin/bash # 簡易的通訊錄數據庫 clear # 清屏。 echo " Contact List" echo " ------- ----" echo "Choose one of the following persons:" echo echo "[E]vans, Roland" echo "[J]ones, Mildred" echo "[S]mith, Julie" echo "[Z]ane, Morris" echo read person case "$person" in # 注意變量是被引用的。 "E" | "e" ) # 同時接受大小寫的輸入。 echo echo "Roland Evans" echo "4321 Flash Dr." echo "Hardscrabble, CO 80753" echo "(303) 734-9874" echo "(303) 734-9892 fax" echo "revans@zzy.net" echo "Business partner & old friend" ;; # 注意用雙分號結束這一個選項。 "J" | "j" ) echo echo "Mildred Jones" echo "249 E. 7th St., Apt. 19" echo "New York, NY 10009" echo "(212) 533-2814" echo "(212) 533-9972 fax" echo "milliej@loisaida.com" echo "Ex-girlfriend" echo "Birthday: Feb. 11" ;; # Smith 和 Zane 的信息稍后添加。 * ) # 缺省設置。 # 空輸入(直接鍵入回車)也是執行這一部分。 echo echo "Not yet in database." ;; esac echo # 練習: # ----- # 修改腳本,使得其可以循環接受多次輸入而不是只顯示一個地址后終止腳本。 exit 0 ``` 你可以用 `case` 來檢測命令行參數。 ```bash #!/bin/bash case "$1" in "") echo "Usage: ${0##*/} <filename>"; exit $E_PARAM;; # 沒有命令行參數,或者第一個參數為空。 # 注意 ${0##*/} 是參數替換 ${var##pattern} 的一種形式。 # 最后的結果是 $0. -*) FILENAME=./$1;; # 如果傳入的參數以短橫線開頭,那么將其替換為 ./$1 #+ 以避免后續的命令將其解釋為一個選項。 * ) FILENAME=$1;; # 否則賦值為 $1。 esac ``` 下面是一個更加直觀的處理命令行參數的例子: ```bash #!/bin/bash while [ $# -gt 0 ]; do # 遍歷完所有參數 case "$1" in -d|--debug) # 檢測是否是 "-d" 或者 "--debug"。 DEBUG=1 ;; -c|--conf) CONFFILE="$2" shift if [ ! -f $CONFFILE ]; then echo "Error: Supplied file doesn't exist!" exit $E_CONFFILE # 找不到文件。 fi ;; esac shift # 檢測下一個參數 done # 摘自 Stefano Falsetto 的 "Log2Rot" 腳本中 "rottlog" 包的一部分。 # 已授權使用。 ``` 樣例 11-27. 使用命令替換生成 `case` 變量 ```bash #!/bin/bash # case-cmd.sh: 使用命令替換生成 "case" 變量。 case $( arch ) in # $( arch ) 返回設備架構。 # 等價于 'uname -m"。 i386 ) echo "80386-based machine";; i486 ) echo "80486-based machine";; i586 ) echo "Pentium-based machine";; i686 ) echo "Pentium2+-based machine";; * ) echo "Other type of machine";; esac exit 0 ``` `case` 還可以用來做字符串模式匹配。 樣例 11-28. 簡單的字符串匹配 ```bash #!/bin/bash # match-string.sh: 使用 'case' 結構進行簡單的字符串匹配。 match_string () { # 字符串精確匹配。 MATCH=0 E_NOMATCH=90 PARAMS=2 # 需要2個參數。 E_BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $E_BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $E_NOMATCH;; esac } a=one b=two c=three d=two match_string $a # 參數個數不夠 echo $? # 91 match_string $a $b # 匹配不到 echo $? # 90 match_string $a $d # 匹配成功 echo $? # 0 exit 0 ``` 樣例 11-29. 檢查輸入 ```bash #!/bin/bash # isaplpha.sh: 使用 "case" 結構檢查輸入。 SUCCESS=0 FAILURE=1 # 以前是FAILURE=-1, #+ 但現在 Bash 不允許返回負值。 isalpha () # 測試字符串的第一個字符是否是字母。 { if [ -z "$1" ] # 檢測是否傳入參數。 then return $FAILURE fi case "$1" in [a-zA-Z]*) return $SUCCESS;; # 是否以字母形式開始? * ) return $FAILURE;; esac } # 可以與 C 語言中的函數 "isalpha ()" 作比較。 isalpha2 () # 測試整個字符串是否都是字母。 { [ $# -eq 1 ] || return $FAILURE case $1 in *[!a-zA-Z]*|"") return $FAILURE;; *) return $SUCCESS;; esac } isdigit () # 測試整個字符串是否都是數字。 { # 換句話說,也就是測試是否是一個整型變量。 [ $# -eq 1 ] || return $FAILURE case $1 in *[!0-9]*|"") return $FAILURE;; *) return $SUCCESS;; esac } check_var () # 包裝后的 isalpha ()。 { if isalpha "$@" then echo "\"$*\" begins with an alpha character." if isalpha2 "$@" then # 其實沒必要檢查第一個字符是不是字母。 echo "\"$*\" contains only alpha characters." else echo "\"$*\" contains at least one non-alpha character." fi else echo "\"$*\" begins with a non-alpha character." # 如果沒有傳入參數同樣同樣返回“存在非字母”。 fi echo } digit_check () # 包裝后的 isdigit ()。 { if isdigit "$@" then echo "\"$*\" contains only digits [0 - 9]." else echo "\"$*\" has at least one non-digit character." fi echo } a=23skidoo b=H3llo c=-What? d=What? e=$(echo $b) # 命令替換。 f=AbcDef g=27234 h=27a34 i=27.34 check_var $a check_var $b check_var $c check_var $d check_var $e check_var $f check_var # 如果不傳入參數會發送什么? # digit_check $g digit_check $h digit_check $i exit 0 # S.C. 改進了本腳本。 # 練習: # ----- # 寫一個函數 'isfloat ()' 來檢測輸入值是否是浮點數。 # 提示:可以參考函數 'isdigit ()',在其中加入檢測合法的小數點即可。 ``` ### `select` `select` 結構是學習自 Korn Shell。其同樣可以用來構建菜單。 ```bash select variable [in list] do command... break done ``` 而效果則是終端會提示用戶輸入列表中的一個選項。注意,`select` 默認使用提示字串3(Prompt String 3,`$PS3`, 即#?),但同樣可以被修改。 樣例 11-30. 使用 `select` 創建菜單 ```bash #!/bin/bash PS3='Choose your favorite vegetable: ' # 設置提示字串。 # 否則默認為 #?。 echo select vegetable in "beans" "carrots" "potatoes" "onions" "rutabagas" do echo echo "Your favorite veggie is $vegetable." echo "Yuck!" echo break # 如果沒有 'break' 會發生什么? done exit # 練習: # ----- # 修改腳本,使得其可以接受其他輸入而不是 "select" 語句中所指定的。 # 例如,如果用戶輸入 "peas,",那么腳本會通知用戶 "Sorry. That is not on the menu." ``` 如果 *in list* 被省略,那么 `select` 將會使用傳入腳本的命令行參數(`$@`)或者傳入函數的參數作為 *list*。 可以與 `for variable [in list]` 中 *in list* 被省略的情況做比較。 樣例 11-31. 在函數中使用 `select` 創建菜單 ```bash #!/bin/bash PS3='Choose your favorite vegetable: ' echo choice_of() { select vegetable # [in list] 被省略,因此 'select' 將會使用傳入函數的參數作為 list。 do echo echo "Your favorite veggie is $vegetable." echo "Yuck!" echo break done } choice_of beans rice carrorts radishes rutabaga spinach # $1 $2 $3 $4 $5 $6 # 傳入了函數 choice_of() exit 0 ``` 還可以參照 [樣例37-3](http://tldp.org/LDP/abs/html/bashver2.html#RESISTOR)。 [^1]: 在寫匹配行的時候,可以在左邊加上左括號 (,使整個結構看起來更加優雅。<pre>case $( arch ) in # $( arch ) 返回設備架構。<br> ( i386 ) echo "80386-based machine";;<br># ^ ^<br> ( i486 ) echo "80486-based machine";;<br> ( i586 ) echo "Pentium-based machine";;<br> ( i686 ) echo "Pentium2+-based machine";;<br> ( * ) echo "Other type of machine";;<br>esac</pre>
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看