amm*_*ite 1 bash case-statement
有什么方法可以检索 case 语句中的选项列表?例如,如果我有这个代码:
tool=$1
case ${tool} in
brdf)
# Do stuff
;;
drift)
# Do other stuff
;;
*)
echo "ERROR: I don't know this tool. Valid options are: brdf, drift"
exit 1
;;
esac
Run Code Online (Sandbox Code Playgroud)
这很容易阅读,但是在从列表中添加/删除工具时,错误消息很容易过时,因为我还需要记住更改那里的名称。
使用这样的数组可以避免重复:
tool=$1
validtools=(brdf drift)
case ${tool} in
${validtools[0]})
# Do stuff
;;
${validtools[1]})
# Do other stuff
;;
*)
echo "ERROR: I don't know this tool. Valid options are: ${validtools[@]}"
exit 1
;;
esac
Run Code Online (Sandbox Code Playgroud)
但这读起来非常糟糕,无论如何,使用硬编码的数组索引来维护会更糟。
有没有一种好的方法可以做到这一点,也许是一些检索可用选项列表的变量或命令,或者我是否只需要记住在添加新选项时更新错误消息?
最常用的方法是作为您的第一个示例。查看 linux 中的所有 init 脚本。
这是有原因的,因为您可以使用以下结构:
case "$a" in
arg1|arg2|arg3) ... ;;
brg1|brg2) ... ;;
brg2) ... ;;
esac
Run Code Online (Sandbox Code Playgroud)
并且将很难自动构建正确usage message的所有可能的变体。
这也是shopt -s extglob允许您在 case statemens 中使用扩展模式匹配的原因。有关示例,请参阅此答案:https : //stackoverflow.com/a/4555979/632407
但是如果你想使用数组,尝试使用关联数组,增加一点可读性。(但无论如何它很糟糕):) 就像下一个:
declare -A arg
initargs() { for a in "$@"; do arg[$a]="$a"; done; }
initargs brd lbrs ubrs
for myarg
do
case "$myarg" in
${arg[brd]}) echo "brd";;
${arg[ubrs]}) echo "ubrs";;
${arg[lbrs]}) echo "lbrs";;
*) echo "Unknown arg =$myarg=. Known are: ${arg[@]}" ;;
esac
done
Run Code Online (Sandbox Code Playgroud)
所以允许的参数是:“brd”“lbrs”“ubrs”和下一个输入的脚本
$ bash argtest ubrs badarg brd
Run Code Online (Sandbox Code Playgroud)
产生:
ubrs
Unknown arg =badarg=. Known are: lbrs ubrs brd
brd
Run Code Online (Sandbox Code Playgroud)