我有以下功能,并想了解如何使用 来设置具有可选值的选项getopt
。
希望-w
采用默认值
region -w -- "Text"
这-w 1
需要可选的数值。
region -w 1 -- "Text"
函数在这里
region ()
{
# Process command line options
shortopts="hw::"
longopts="help,version,warning:"
opts=$(getopt -o "$shortopts" -l "$longopts" \
-n "$(basename $0)" -- "$@")
if [ $? -eq 0 ]; then
eval "set -- ${opts}"
while [ $# -gt 0 ]; do
case "$1" in
-h|-\?|--help)
printf "%s\n" "Todo."
shift
break
;;
-w|--warning)
case "$2" in
"1") local -r warn="first"; shift 2 ;;
*) local -r warn="all"; shift 2 ;;
esac
local -r f=1
;;
--)
local -r f=1
shift
break
;;
esac
done
else
shorthelp=1 # getopt returned (and reported) an error.
fi
}
答案1
您可能不会喜欢这个答案:为了向可选地采用参数的选项提供参数,您不允许使用空格:
$ getopt -o 'w::' -- -w -- arg
-w '' -- 'arg'
$ getopt -o 'w::' -- -w 1 -- arg
-w '' -- '1' 'arg'
$ getopt -o 'w::' -- -w1 -- arg
-w '1' -- 'arg'
同样,对于选项长参数,您必须使用=
$ getopt -o '' -l 'warning::' -- --warning -- arg
--warning '' -- 'arg'
$ getopt -o '' -l 'warning::' -- --warning 1 -- arg
--warning '' -- '1' 'arg'
$ getopt -o '' -l 'warning::' -- --warning=1 -- arg
--warning '1' -- 'arg'
从手册页:
一个简单的短选项是一个“-”后跟一个短选项字符[...]如果该选项有一个可选参数,必须直接写在选项字符之后如果存在的话。
长选项通常以 '--' 开头 [...] 如果选项有可选参数,它必须直接写在长选项名称之后,并用“=”分隔,如果存在(如果添加“=”但其后面没有任何内容,则会被解释为好像没有参数存在;这是一个小错误,请参阅错误)。
只是关于代码布局的代码审查评论:在 if-else-fi 构造中,将短分支放在第一位。在这里,当我到达 时else
,我必须进行扫描以记住if
情况是什么。
这还允许您以“断言”风格编写并减少函数的“主”代码:
region ()
{
# Process command line options
shortopts="hw::"
longopts="help,version,warning:"
opts=$(getopt -o "$shortopts" -l "$longopts" \
-n "$(basename $0)" -- "$@")
if [ $? -ne 0 ]; then
shorthelp=1 # getopt returned (and reported) an error.
return
fi
eval "set -- $opts"
# ...
另外,您可以直接检查退出状态并仍然分配给变量(我还在此处删除了基本名称调用)
if ! opts=$(getopt -o "$shortopts" -l "$longopts" -n "${0##*/}" -- "$@")
then
shorthelp=1 # getopt returned (and reported) an error.
return
fi
使用 -w 我设置 level=1。否则,对于 -wNUM 我设置 level=NUM
local level=0
#...
case "$1" in
-w|--warning)
level=${2:-"1"}
;;
即采用${var:-default}
参数扩展的形式。