I like this dispatch trick:
build() { ... }
run() { ... }
cmd="$1"
shift
$cmd "$@"
build() { ... }
run() { ... }
cmd="$1"
shift
$cmd "$@"
As soon as any complexity or validation is needed I move to python, which is usually a better fit, and arguably even more portable.