bash 捕获 getopt 无效选项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7663481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Trapping getopt invalid options
提问by Tom Auger
I'm using getopt(not getops) to provide the ability for my bash script to process options and switches (both long --option and short -o forms).
我正在使用getopt(not getops) 为我的 bash 脚本提供处理选项和开关(长 --option 和短 -o 形式)的能力。
I'd like to be able to trap invalid options and handle them, typically echoing out that the user should try cmd --helpand then exiting the script.
我希望能够捕获无效选项并处理它们,通常会回应用户应该尝试cmd --help然后退出脚本。
Thing is, the invalid options are being caught by getopt, which is itself outputting a message such as "getopt: invalid option -- 'x'"
问题是,无效的选项被 getopt 捕获,它本身输出诸如“getopt: invalid option -- 'x'”之类的消息
Here's the pattern I'm using to set my getopt parameters:
这是我用来设置 getopt 参数的模式:
set -- $(getopt -o $SHORT_OPTIONS -l $LONG_OPTIONS -- "$@")
where both $LONG_OPTIONS and $SHORT_OPTIONS are a comma-delimited list of options.
其中 $LONG_OPTIONS 和 $SHORT_OPTIONS 都是逗号分隔的选项列表。
Here's how I handle processing the options:
以下是我处理选项的方式:
while [ $# -gt 0 ]
do
case "" 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 is not a valid option."
echo "Try './cmd.sh --help for more information."
shift
exit
;;
esac
done
getopt -qwill suppress the output, but my trapping scheme within the casestatement still fails to do what I expect. Instead, the program just executes, despite the invalid arguments.
getopt -q将抑制输出,但我在case语句中的陷阱方案仍然无法达到我的预期。取而代之的是,尽管参数无效,程序还是会执行。
采纳答案by l0b0
回答by mklement0
This is not the most robust solution, but it's reasonable; it relies on the following:
这不是最健壮的解决方案,但它是合理的;它依赖于以下几点:
- The error message that
getoptprints is prefixed with "getopt: " - The assumption is that it's acceptable to pass through a cleaned-up version of
getopt's error message, augmented with custom information.
getopt打印的错误信息以“getopt:”为前缀- 假设是传递
getopt的错误消息的清理版本是可以接受的,并增加了自定义信息。
Code snippet:
代码片段:
# 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
回答by The Tomahawk
Do you have to use getopt at all? If you just use
你必须使用 getopt 吗?如果你只是使用
while [ $# -gt 0 ]; do
case "" in
-d|--diff)
diff_exec=(${2-})
shift
;;
-h|--help)
usage
exit
;;
--)
break
;;
*)
usage
;;
esac
shift
done
Then you own code is doing the checking.
然后你自己的代码正在做检查。
回答by Steve
I found this to work as the last item in the getopts case statement:
我发现这可以作为 getopts case 语句中的最后一项:
*) eval echo "Unrecognized arg \$$[OPTIND-1]"; usage; exit ;;
*) eval echo "无法识别的参数 \$$[OPTIND-1]"; 用法; 出口 ;;
回答by dpminusa
Here is a command line parsing I have used. It could be improved with more parsing logic to handle missing options and parameters.
这是我使用的命令行解析。可以通过更多的解析逻辑来改进它来处理丢失的选项和参数。
For the command line: -a AA -b BB -c CC, the result s/b a=AA b=BB c=CC
对于命令行:-a AA -b BB -c CC,结果s/ba=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
回答by Dimitre Radoulov
I'm not sure if this can help, but getopt(1)uses getopt(3)and if I recall correctly getopt(3)suppress error reporting if the fist character of the OPTSTRINGis a colon.
我不确定这是否有帮助,但getopt(1)使用getopt(3),如果我没记错的话,如果OPTSTRING的第一个字符是冒号,getopt(3) 会抑制错误报告。

