我正在使用getopt
(而非getops
)为我的bash脚本提供处理选项和切换(long -option和short -o表单)的能力。
我希望能够捕获无效选项并处理它们,通常会回应用户应该尝试cmd --help
然后退出脚本。
事实是,getopt捕获了无效选项,它本身输出了一条消息,例如“getopt:invalid option - 'x'”
这是我用来设置我的getopt参数的模式:
set -- $(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@")
其中$ LONG_OPTIONS和$ SHORT_OPTIONS都是以逗号分隔的选项列表。
以下是处理选项的方法:
while [ $# -gt 0 ]
do
case "$1" in
-h|--help)
cat <<END_HELP_OUTPUT
Help
----
Usage: ./cmd.sh
END_HELP_OUTPUT
shift;
exit
;;
--opt1)
FLAG1=true
shift
;;
--opt2)
FLAG2=true
shift
;;
--)
shift
break
;;
*)
echo "Option $1 is not a valid option."
echo "Try './cmd.sh --help for more information."
shift
exit
;;
esac
done
getopt -q
会抑制输出,但case
语句中的陷阱方案仍然无法达到预期效果。相反,尽管参数无效,程序才会执行。
答案 0 :(得分:9)
This这种风格对我有用:
params="$(getopt -o d:h -l diff:,help --name "$cmdname" -- "$@")"
if [ $? -ne 0 ]
then
usage
fi
eval set -- "$params"
unset params
while true
do
case $1 in
-d|--diff)
diff_exec=(${2-})
shift 2
;;
-h|--help)
usage
exit
;;
--)
shift
break
;;
*)
usage
;;
esac
done
答案 1 :(得分:1)
这不是最强大的解决方案,但它是合理的;它依赖于以下内容:
getopt
打印的错误消息前缀为“getopt:”getopt
错误消息,并使用自定义信息进行扩充。代码段:
# Invoke getopt; suppress its stderr initially.
args=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>/dev/null)
if [[ $? -ne 0 ]]; then # getopt reported failure
# Rerun the same getopt command so we can capture stderr output *only* this time.
# Inefficient (and a potential maintenance headache, if literals were involved), but this will only execute in case of invalid input.
# Alternatively, redirect the first getopt invocation's stderr output to a temp. file and read it here.
errmsg=$(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@" 2>&1 1>&-)
# Strip getopt's prefix and augment with custom information.
echo -e "${errmsg#getopt: }\nTry './cmd.sh --help for more information." 1>&2
exit 1
fi
答案 2 :(得分:1)
你必须使用getopt吗?如果您只是使用
while [ $# -gt 0 ]; do
case "$1" in
-d|--diff)
diff_exec=(${2-})
shift
;;
-h|--help)
usage
exit
;;
--)
break
;;
*)
usage
;;
esac
shift
done
然后你自己的代码正在进行检查。
答案 3 :(得分:1)
我发现这可以作为getopts案例陈述中的最后一项:
*)eval echo“无法识别的arg \ $$ [OPTIND-1]”;用法;退出;;
答案 4 :(得分:0)
我不确定这是否有帮助,但 getopt(1)使用 getopt(3)并且如果我没记错的话 getopt(3)< / em>如果 OPTSTRING 的第一个字符是冒号,则抑制错误报告。
答案 5 :(得分:0)
这是我使用过的命令行解析。它可以通过更多的解析逻辑来改进,以处理丢失的选项和参数。
对于命令行:-a AA -b BB -c CC,结果s / b a = AA b = BB c = CC
OPT=( "$@" ) # Parses the command line into words.
for [[ I=0;I<${#OPT[@]};I++ ]]
do
case "${OPT[$I]}" in
-a) a=${OPT[$I+1]} ;;
-b) b=${OPT[$I+1]} ;;
-c) c=${OPT[$I+1]} ;;
esac
done