funcs=($(declare -F -p | cut -d " " -f 3))

until
    if [ ! -z "$1" ]; then
        # check if the first arg is a function in this file, or use a default
        if [[ " ${funcs[@]} " =~ " $1 " ]]; then
            cmd=$1
            shift 1
        else
            cmd="a"
        fi

        $cmd "$@"
        if [ $? == 127 ]; then
            help
        fi

        exit
    else
        help
    fi
do
    echo
done

--------------------------------

测试:

#!/bin/bash

#set -e

help(){
    echo "help"
}

a(){
echo "aaaaaaa"
}

b(){
echo "bbbbbb"
}

c(){
echo "cccccc"
}

funcs=($(declare -F -p | cut -d " " -f 3))

until
    if [ ! -z "$1" ]; then
        # check if the first arg is a function in this file, or use a default
        if [[ " ${funcs[@]} " =~ " $1 " ]]; then
            cmd=$1
            shift 1
        else
            cmd="a"
        fi

        $cmd "$@"
        if [ $? == 127 ]; then
            help
        fi

        exit
    else
        help
    fi
do
    echo
done

-----------------------

[root@mhc sh]# ./a
help
[root@mhc sh]# ./a a
aaaaaaa
[root@mhc sh]# ./a b
bbbbbb
[root@mhc sh]# ./a c
cccccc
[root@mhc sh]# ./a  a b
aaaaaaa
[root@mhc sh]# ./a  a b c
aaaaaaa
[root@mhc sh]# ./a  b c
bbbbbb
[root@mhc sh]# ./a  b c d
bbbbbb
[root@mhc sh]# ./a   d
aaaaaaa
-------------------------------------

a(){
echo "$1"
}

---------

[root@mhc sh]# ./a a hahah
hahah
---------------------------

=====================================================

until
cmd=$1
if [[ -z "$cmd" ]]; then
help
fi
shift 1
$cmd "$@"
[ "$?" -ne 127 ]
do
help
exit
done