介绍
最近一直在写自动化测试脚本,随着功能越来越多,需要给使用者提供更多的选项了。之前一直是通过解析位置参数来获取选项,现在需要支持更多更复杂的选项,深感力不从心,于是寻找到了一个选项解析利器: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 "$@"
使用"$@"可以将参数原封不动传递给函数
- 加双引号是防止参数中可能有空格,空格会被shell自动视为分隔符
- "$@"会将每个参数用双引号括起来传递进去,而"@*"则是所有参数括在双引号中,作为一个参数传入函数
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。