getopts 的用法
Linux 下很多命令都带有选项,比如:
ls -l ~/
sort -n
tail -f XXX.log
是否想让 shell 脚本也具有这样的功能呢?如果直接使用 shell 的字符串处理来分析参数,还是比较麻烦的,我们需要考虑传入的参数哪些是选项,哪些是选项的值,哪些是正常的参数等等,为了更好的体验,可能还要支持选项合并,类似于 sort -rn
。
幸运的是,Linux 有一个命令可以帮我们完成这些事情,它就是 getopts
,使用起来也比较简单。可以先看一个示例脚本[1]:
#!/bin/bash
echo "OPTIND: $OPTIND"
while getopts ":pq:" optname
do
case "$optname" in
"p")
echo "选项 $optname 被指定"
;;
"q")
echo "选项 $optname 有参数值 $OPTARG"
;;
"?")
echo "未知的选项 $OPTARG"
;;
":")
echo "$OPTARG 未指定参数值"
;;
*)
# Should not occur
echo "当处理选项时,发生未知错误"
;;
esac
echo "OPTIND: $OPTIND"
done
我们将错误处理的部分去除,核心逻辑其实是这样的:
#!/bin/bash
while getopts ":pq:" optname
do
case "$optname" in
"p")
echo "选项 $optname 被指定"
;;
"q")
echo "选项 $optname 有参数值 $OPTARG"
;;
esac
done
这个脚本有两个选项,-p
和 -q
,你一定会问的问题:
- getopts 第一个参数中的两个冒号分别什么意思
$optname
和$OPTARG
代表什么
为了更好理解,我们再增加一个选项 -t
,将 ":pq:"
改为 ":pq:t:"
,再来解释。
问题一
第一个冒号,表示静默模式,也就是阻止报错,阻止什么报错呢?比如不合法的选项,或者未指定选项的参数值之类的。
选项字母后的冒号表示该选项需要一个参数值,在这个例子中, -t
和 -q
都需要跟一个参数值,而 -p
则不要求。
正确的运行该脚本,要像这样子:
./testargs.sh -p -t 1 -q 2
问题二
第二个问题,聪明如你,应该已经猜出来了,$optname
是选项名(p, t, q等),$OPTARG
中存了对应选项名的参数值(前提是选项字母后有冒号)。
错误处理
现在我们再回头看完整的脚本示例,来到错误处理的部分。
在静默模式下,可能出现以下两种错误情况。
- 如果发现不能识别的选项,则
$optname
将包含一个?
,而$OPTARG
将包含该未知选项的名称。 - 如果一个选项需要值,但是找不到这个值,则
$optname
将包含一个:
,而$OPTARG
将包含丢失参数的选项的名称。
至于$OPTIND
,它代表待处理的下一个参数的索引,初始值为1.
- 原文作者:lon3r
- 原文链接:https://tlog.cc/post/linux/getopts-%E7%9A%84%E7%94%A8%E6%B3%95/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。