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.
本文链接:https://blog.xiaoyuyu.cn/post/getopts的用法.html,参与评论 »
--EOF--
发表于 2019-12-13 14:47:00。
本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。更多说明 »
提醒:本文最后更新于 2149 天前,文中所描述的信息可能已发生改变,请谨慎使用。
Comments