1

介绍

最近一直在写自动化测试脚本,随着功能越来越多,需要给使用者提供更多的选项了。之前一直是通过解析位置参数来获取选项,现在需要支持更多更复杂的选项,深感力不从心,于是寻找到了一个选项解析利器:getotps。

getopts是一个Linux内建命令,使用简单,不过只支持短选项,如-u、-p这样的选项,不支持长选项。

示例

这里定义一个shell函数,用于解析传递给脚本的选项

  while getopts "b:dgm:n:p:uv" opt; do
    case ${opt} in
    b)
      branch=$OPTARG
      ;;
    d)
      debug=1
      ;;
    g)
      isGif=1
      pkg=${gifPkg}
      activity=${gifHomePage}
      ;;
    m)
      if [[ "$MODE_FIRST_OPEN_AFTER_KILL_APP" != "$OPTARG" ]] &&
        [[ "$MODE_FIRST_OPEN_AFTER_CLEAR_APP" != "$OPTARG" ]]; then
        echo "非法模式: $OPTARG"
        exit
      fi
      mode=$OPTARG
      ;;
    n)
      maxCount=$OPTARG
      if [[ ${maxCount} -le 0 ]]; then
        echo "-n参数不合法:$maxCount"
        exit
      fi
      ;;
    p)
      dataDirPrefix=$OPTARG
      ;;
    u)
      needUpgrade=1
      ;;
    :)
      exit
      ;;
    ?)
      exit
      ;;
    *)
      echo "*分支:${OPTARG}"
      ;;
    esac
  done

使用

./test.sh -b hello -d -g -p world

分析

getopts命令需要两个参数
第一个是选项描述字符串,如上例中的"b:dgm:n:p:uv",声明了要处理的短参数
第二个是变量,如上例中的opt,getopts会把解析到的选项名赋值给该变量,同时把选项的参数赋值给内建变量OPTARG,然后检查选项参数是否合法,或者保存该参数等待。

选项描述字符串的格式:
一个字母代表一个短选项,字母后带冒号说明该选项需要参数,否则就是无参选项。

选项描述字符串还可以在开头加上冒号,如":b:dgm:n:p:uv"
不管有没有冒号,都有以下规则:
若遇到未指定的选项,会走问号分支,若选项需要参数但未收到,则走冒号分支
区别是:
开头没有冒号,会自动提示命令错误还是需要参数,分号冒号分支中可从OPTARG变量中获取错误的选项或参数,然后自己处理
开头有冒号,错误提示会被压制,分支中收到OPTARG则是空的,似乎被getopts取走了,而且只走问号分支;所以这种情况下就没必要自己处理了

还有一个内建参数OPTIND,该变量指示getopts下一个要解析的位置,一般用不到

实际使用

实际使用中选项解析可能要很多行,最好是抽取成一个函数。要注意的是如何将脚本的参数都传递给函数。

parseArgs() {
  while getopts "b:dgm:n:p:uv" opt; do
  # case处理选项及其参数
  done
}

parseArgs "$@"

使用"$@"可以将参数原封不动传递给函数

  1. 加双引号是防止参数中可能有空格,空格会被shell自动视为分隔符
  2. "$@"会将每个参数用双引号括起来传递进去,而"@*"则是所有参数括在双引号中,作为一个参数传入函数

鲸鱼
3 声望0 粉丝

天空一声巨响,老子闪亮登场✨!