I wrote a bash script that takes a command as the first positional parameter and uses a case construct as a dispatch similar to the following:
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
This script decides what function to call based on $1
and then passes the remaining arguments to that function. I would like to add the ability dispatch on distinct partial matches, but I want to do it in an elegant way (elegant defined as a way that is both easy to read and is not so verbose as to be an eyesore or a distraction).
The obvious functioning (but not elegant) solution might be something like this:
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
As you can see, explicitly enumerating all distinct permutations of each command name can get really messy.
For a moment, I thought it might be alright to use a wildcard match like this:
case $cmd in
com*)
do_command $*
;;
cop*)
do_copy $*
;;
i*)
do_imperative $*
;;
*)
echo "Usage: $0 [ command | copy | imperative ]" >&2
;;
esac
This is less of an eyesore. However, this could result in undesirable behavior such as where do_command
is called when $1
is given as "comblah" or something else that shouldn't be recognized as a valid argument.
My question is: What is the most elegant (as defined above) way to correctly dispatch such a command where the user can provide any distinct truncated form of the expected commands?