我编写了一个 bash 脚本,它将命令作为第一个位置参数,并使用 case 构造作为类似于以下的调度:
do_command() {
# responds to invocation `$0 command ...`
}
do_copy() {
# respond to invocation: `$0 copy...`
}
do_imperative() {
# respond to invocation: `$0 imperative ...`
}
cmd=$1
shift
case $cmd in
command)
do_command $*
;;
copy)
do_copy $*
;;
imperative)
do_imperative $*
;;
*)
echo "Usage: $0 [ command | copy | imperative ]" >&2
;;
esac
该脚本决定基于哪个函数调用$1
,然后将剩余的参数传递给该函数。我想在不同的部分匹配上添加能力调度,但我想以一种优雅的方式来做到这一点(优雅的定义是一种既易于阅读又不会过于冗长以至于令人眼花缭乱或分散注意力的方式)。
显而易见的功能(但不优雅)的解决方案可能是这样的:
case $cmd in
command|comman|comma|comm|com)
do_command $*
;;
copy|cop)
do_copy $*
;;
imperative|imperativ|imperati|imperat|impera|imper|impe|imp|im|i)
do_imperative $*
;;
*)
echo "Usage: $0 [ command | copy | imperative ]" >&2
;;
esac
如您所见,显式枚举每个命令名称的所有不同排列可能会变得非常混乱。
有那么一刻,我认为使用这样的通配符匹配可能没问题:
case $cmd in
com*)
do_command $*
;;
cop*)
do_copy $*
;;
i*)
do_imperative $*
;;
*)
echo "Usage: $0 [ command | copy | imperative ]" >&2
;;
esac
这不那么碍眼。但是,这可能会导致不良行为,例如 where do_command
is called when $1
is given as "comblah" 或其他不应被视为有效参数的东西。
我的问题是:在用户可以提供任何不同截断形式的预期命令的情况下,正确调度此类命令的最优雅(如上定义)方式是什么?