Skip to content
SRE运维进阶之路SRE运维进阶之路
github icon
    • 第一部分 初见shell

      • 第一章 为什么使用shell编程
        • 第二章 和Sha-Bang(#!)一起出发

          • 2.1 调用一个脚本
            • 2.2 牛刀小试
          • 第二部分 shell基础

            • 第三章 特殊字符
              • 第四章 变量与参数

                • 4.1 变量替换
                  • 4.2 变量赋值
                    • 4.3 Bash变量是弱类型的
                      • /code/shell/part2/04_4_special_variable_types
                      • 第五章 引用

                        • 5.1 引用变量
                          • 5.2 转义
                          • 第六章 退出与退出状态
                            • 第七章 测试

                              • 7.1 测试结构
                                • 7.2 文件测试操作
                                  • 7.3 其他比较操作
                                    • 7.4 嵌套 if/then 条件测试
                                      • 7.5 牛刀小试
                                      • 第八章 运算符相关话题

                                        • 8.1 运算符
                                          • 8.2 数字常量
                                            • 8.3 双圆括号结构
                                              • 8.4 运算符优先级
                                            • 第三部分 shell进阶

                                              • 第九章 换个角度看变量

                                                • 9.1 内部变量
                                                  • 9.2 变量类型标注:declare 与 typeset
                                                    • 9.2.1 declare 的另类用法
                                                      • 9.3 $RANDOM:生成随机数
                                                      • 第十章 变量处理

                                                        • 10.1 字符串处理
                                                          • 10.1.1 使用 awk 处理字符串
                                                            • 10.1.2 参考资料
                                                              • 10.2 参数替换
                                                              • 第十一章 循环与分支

                                                                • 11.1 循环
                                                                  • 11.2 嵌套循环
                                                                    • 11.3 循环控制
                                                                      • 11.4 测试与分支
                                                                        • case (in) / esac
                                                                          • select
                                                                        • 第十二章 命令替换
                                                                          • 第十三章 算术扩展
                                                                          • 第四部分 命令
                                                                            • 第五部分 高级话题

                                                                              • 18 正则表达式

                                                                                • 18.1 正则表达式简介
                                                                                  • 18.2文件名替换
                                                                                    • 18.3 正则表达式对照表
                                                                                    • 19 嵌入文档
                                                                                      • 20 I/O 重定向

                                                                                        • 20.1 使用 exec
                                                                                          • 20.2 重定向代码块
                                                                                            • 20.3 应用程序
                                                                                            • 第二十一章 子shell
                                                                                              • 第二十二章. 限制模式的Shell
                                                                                                • 第二十三章. 进程替换
                                                                                                  • 24 函数

                                                                                                    • 24.1 复杂函数和函数复杂性
                                                                                                      • 24.2 局部变量
                                                                                                        • 24.3 不使用局部变量的递归
                                                                                                        • 25. 别名
                                                                                                          • 26. 列表结构
                                                                                                            • 27 数组
                                                                                                              • 30 网络编程
                                                                                                                • 33 选项
                                                                                                                  • 第34章 陷阱
                                                                                                                    • 第36章 杂项
                                                                                                                      • echo命令
                                                                                                                      • 第六部分 Google Shell 风格指南
                                                                                                                      • 前端学习笔记

                                                                                                                        11.4 测试与分支

                                                                                                                        author iconLinuxStorycalendar icon2021年5月11日category icon
                                                                                                                        • Linux
                                                                                                                        tag icon
                                                                                                                        • Bash
                                                                                                                        timer icon大约 6 分钟

                                                                                                                        此页内容
                                                                                                                        • case (in) / esac
                                                                                                                        • select

                                                                                                                        # 11.4 测试与分支

                                                                                                                        case 和 select 结构并不属于循环结构,因为它们并没有反复执行代码块。但是和循环结构相似的是,它们会根据代码块顶部或尾部的条件控制程序流。

                                                                                                                        下面介绍两种在代码块中控制程序流的方法:

                                                                                                                        # case (in) / esac

                                                                                                                        在 shell 脚本中,case 模拟了 C/C++ 语言中的 switch,可以根据条件跳转到其中一个分支。其相当于简写版的 if/then/else 语句。很适合用来创建菜单选项哟!

                                                                                                                        case "$variable" in
                                                                                                                          "$condition1" )
                                                                                                                            command...
                                                                                                                          ;;
                                                                                                                          "$condition2" )
                                                                                                                            command...
                                                                                                                          ;;
                                                                                                                        esac
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8

                                                                                                                        note

                                                                                                                        • 对变量进行引用不是必须的,因为在这里不会进行字符分割。

                                                                                                                        • 条件测试语句必须以右括号 ) 结束。[1]

                                                                                                                        • 每一段代码块都必须以双分号 ;; 结束。

                                                                                                                        • 如果测试条件为真,其对应的代码块将被执行,而后整个 case 代码段结束执行。

                                                                                                                        • case 代码段必须以 esac 结束(倒着拼写case)。

                                                                                                                        样例 11-25. 如何使用 case

                                                                                                                        #!/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
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22
                                                                                                                        23
                                                                                                                        24
                                                                                                                        25

                                                                                                                        样例 11-26. 使用 case 创建菜单

                                                                                                                        #!/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
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22
                                                                                                                        23
                                                                                                                        24
                                                                                                                        25
                                                                                                                        26
                                                                                                                        27
                                                                                                                        28
                                                                                                                        29
                                                                                                                        30
                                                                                                                        31
                                                                                                                        32
                                                                                                                        33
                                                                                                                        34
                                                                                                                        35
                                                                                                                        36
                                                                                                                        37
                                                                                                                        38
                                                                                                                        39
                                                                                                                        40
                                                                                                                        41
                                                                                                                        42
                                                                                                                        43
                                                                                                                        44
                                                                                                                        45
                                                                                                                        46
                                                                                                                        47
                                                                                                                        48
                                                                                                                        49
                                                                                                                        50
                                                                                                                        51
                                                                                                                        52
                                                                                                                        53
                                                                                                                        54
                                                                                                                        55
                                                                                                                        56
                                                                                                                        57
                                                                                                                        58
                                                                                                                        59
                                                                                                                        60
                                                                                                                        61
                                                                                                                        62
                                                                                                                        63
                                                                                                                        64

                                                                                                                        你可以用 case 来检测命令行参数。

                                                                                                                        #!/bin/bash
                                                                                                                        
                                                                                                                        case "$1" in
                                                                                                                          "") echo "Usage: ${0##*/} <filename>"; exit $E_PARAM;;
                                                                                                                                              # 没有命令行参数,或者第一个参数为空。
                                                                                                                                              # 注意 ${0##*/} 是参数替换 ${var##pattern} 的一种形式。
                                                                                                                                              # 最后的结果是 $0.
                                                                                                                          
                                                                                                                          -*) FILENAME=./$1;; #  如果传入的参数以短横线开头,那么将其替换为 ./$1
                                                                                                                                              #+ 以避免后续的命令将其解释为一个选项。
                                                                                                                          
                                                                                                                          * ) FILENAME=$1;;   # 否则赋值为 $1。
                                                                                                                        esac                  
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13

                                                                                                                        下面是一个更加直观的处理命令行参数的例子:

                                                                                                                        #!/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" 包的一部分。
                                                                                                                        # 已授权使用。
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22

                                                                                                                        样例 11-27. 使用命令替换生成 case 变量

                                                                                                                        #!/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  
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13

                                                                                                                        case 还可以用来做字符串模式匹配。

                                                                                                                        样例 11-28. 简单的字符串匹配

                                                                                                                        #!/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
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22
                                                                                                                        23
                                                                                                                        24
                                                                                                                        25
                                                                                                                        26
                                                                                                                        27
                                                                                                                        28
                                                                                                                        29
                                                                                                                        30
                                                                                                                        31
                                                                                                                        32
                                                                                                                        33
                                                                                                                        34
                                                                                                                        35
                                                                                                                        36

                                                                                                                        样例 11-29. 检查输入

                                                                                                                        #!/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 ()',在其中加入检测合法的小数点即可。
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22
                                                                                                                        23
                                                                                                                        24
                                                                                                                        25
                                                                                                                        26
                                                                                                                        27
                                                                                                                        28
                                                                                                                        29
                                                                                                                        30
                                                                                                                        31
                                                                                                                        32
                                                                                                                        33
                                                                                                                        34
                                                                                                                        35
                                                                                                                        36
                                                                                                                        37
                                                                                                                        38
                                                                                                                        39
                                                                                                                        40
                                                                                                                        41
                                                                                                                        42
                                                                                                                        43
                                                                                                                        44
                                                                                                                        45
                                                                                                                        46
                                                                                                                        47
                                                                                                                        48
                                                                                                                        49
                                                                                                                        50
                                                                                                                        51
                                                                                                                        52
                                                                                                                        53
                                                                                                                        54
                                                                                                                        55
                                                                                                                        56
                                                                                                                        57
                                                                                                                        58
                                                                                                                        59
                                                                                                                        60
                                                                                                                        61
                                                                                                                        62
                                                                                                                        63
                                                                                                                        64
                                                                                                                        65
                                                                                                                        66
                                                                                                                        67
                                                                                                                        68
                                                                                                                        69
                                                                                                                        70
                                                                                                                        71
                                                                                                                        72
                                                                                                                        73
                                                                                                                        74
                                                                                                                        75
                                                                                                                        76
                                                                                                                        77
                                                                                                                        78
                                                                                                                        79
                                                                                                                        80
                                                                                                                        81
                                                                                                                        82
                                                                                                                        83
                                                                                                                        84
                                                                                                                        85
                                                                                                                        86
                                                                                                                        87
                                                                                                                        88
                                                                                                                        89
                                                                                                                        90
                                                                                                                        91
                                                                                                                        92
                                                                                                                        93
                                                                                                                        94
                                                                                                                        95
                                                                                                                        96
                                                                                                                        97
                                                                                                                        98
                                                                                                                        99
                                                                                                                        100
                                                                                                                        101
                                                                                                                        102
                                                                                                                        103
                                                                                                                        104
                                                                                                                        105
                                                                                                                        106

                                                                                                                        # select

                                                                                                                        select 结构是学习自 Korn Shell。其同样可以用来构建菜单。

                                                                                                                        select variable [in list]
                                                                                                                        do
                                                                                                                         command...
                                                                                                                         break
                                                                                                                        done
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5

                                                                                                                        而效果则是终端会提示用户输入列表中的一个选项。注意,select 默认使用提示字串3(Prompt String 3,$PS3, 即#?),但同样可以被修改。

                                                                                                                        样例 11-30. 使用 select 创建菜单

                                                                                                                        #!/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."
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22

                                                                                                                        如果 in list 被省略,那么 select 将会使用传入脚本的命令行参数($@)或者传入函数的参数作为 list。

                                                                                                                        可以与 for variable [in list] 中 in list 被省略的情况做比较。

                                                                                                                        样例 11-31. 在函数中使用 select 创建菜单

                                                                                                                        #!/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
                                                                                                                        
                                                                                                                        1
                                                                                                                        2
                                                                                                                        3
                                                                                                                        4
                                                                                                                        5
                                                                                                                        6
                                                                                                                        7
                                                                                                                        8
                                                                                                                        9
                                                                                                                        10
                                                                                                                        11
                                                                                                                        12
                                                                                                                        13
                                                                                                                        14
                                                                                                                        15
                                                                                                                        16
                                                                                                                        17
                                                                                                                        18
                                                                                                                        19
                                                                                                                        20
                                                                                                                        21
                                                                                                                        22
                                                                                                                        23
                                                                                                                        24

                                                                                                                        还可以参照 样例37-3open in new window。


                                                                                                                        1. 在写匹配行的时候,可以在左边加上左括号 (,使整个结构看起来更加优雅。

                                                                                                                          case $( arch ) in   # $( arch ) 返回设备架构。
                                                                                                                          ( 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
                                                                                                                          ↩︎

                                                                                                                        edit icon编辑此页open in new window
                                                                                                                        上次编辑于: 2022/4/27 15:33:00
                                                                                                                        贡献者: clay-wangzhi
                                                                                                                        上一页
                                                                                                                        11.3 循环控制
                                                                                                                        备案号:冀ICP备2021007336号
                                                                                                                        Copyright © 2023 LinuxStory