getopt命令中选项字符串":b:"里首个冒号的含义及相关验证问询
getopt命令中选项字符串":b:"里首个冒号的含义及相关验证问询
嘿,我来给你把这个问题说透!首先先同步下我这边的环境,和你提供的差不多:
bash --version | grep [r]elease GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu) getopt --version getopt from util-linux 2.38.1
先从getopt的手册内容说起,它的PARSING部分明确说了:
一个简单的短选项是
-后面跟一个短选项字符。如果选项需要必填参数,它可以直接跟在选项字符后面,或者作为下一个参数(即命令行上用空格分隔)。如果选项是可选参数,那么如果有参数的话必须直接跟在选项字符后面。
回到你问的选项字符串开头的冒号——这个冒号的作用是让getopt进入「静默错误处理模式」。默认情况下,要是你输入了未定义的选项,或者必填参数的选项没给参数,getopt会直接蹦出错误提示然后退出;但如果选项字符串以冒号开头,它就不会自己输出错误了,而是把错误相关的信息通过返回的参数传递给脚本,让我们可以自己写逻辑处理这些错误,比如自定义错误提示、做额外的兼容操作啥的。
先看你提供的那个用来验证可选参数-b的测试脚本:
# 编辑test.sh arg="b is B by default" TEMP=$(getopt -o b:: -- "$@") eval set -- "$TEMP" while true; do case "$1" in -b) arg="$2" shift 2;; --) shift break;; esac done echo "$arg"
这个脚本的测试结果你也列了一部分:
# 不带任何参数运行 bash test.sh b is B by default # 带-b和紧跟的参数c运行 bash test.sh -bc # 输出会是"c",因为-b是可选参数,紧跟的字符会被当作它的参数
那如果我们给选项字符串加上开头的冒号,改成:b::,再给脚本加上错误处理的逻辑,就能看到它的作用了:
arg="b is B by default" TEMP=$(getopt -o :b:: -- "$@") eval set -- "$TEMP" while true; do case "$1" in -b) arg="$2" shift 2;; # 处理未知选项的情况 \?) echo "哎呀,输入了未定义的选项: $2" exit 1;; # 处理参数缺失的情况(如果是必填参数的选项会触发) :) echo "提示:选项$2需要对应的参数哦" exit 1;; --) shift break;; esac done echo "$arg"
现在测试这个带首冒号的脚本:
# 输入一个未定义的选项-x bash test.sh -x # 不会弹出getopt默认的错误,而是输出我们自定义的"哎呀,输入了未定义的选项: x" # 要是把选项改成必填参数的`:b:`,然后不带参数运行 bash test.sh -b # 会输出"提示:选项-b需要对应的参数哦",而不是getopt自带的错误提示
简单总结下这个首冒号的核心功能:
- 关闭
getopt的默认错误输出,切换到静默模式 - 把错误类型(未知选项/参数缺失)通过特定的case分支(
\?和:)传递,让我们能自定义错误处理逻辑
备注:内容来源于stack exchange,提问作者showkey
相关产品推荐
相关产品推荐

