get a list of function names in a shell script [du

2019-01-09 04:55发布

问题:

This question already has an answer here:

  • How do I list the functions defined in my shell? 6 answers

I have a Bourne Shell script that has several functions in it, and allows to be called in the following way:

my.sh <func_name> <param1> <param2>

Inside func_name() will be called with param1 and param2.

I want to create a "help" function that would just list all available functions, even without parameters.

The question: how do I get a list of all function names in a script from inside the script?

I'd like to avoid having to parse it and look for function patterns. Too easy to get wrong.

Thanks, Alex

update: the code. Wanted my help() function be like main() - a function added to the code is added to the help automatically.

#!/bin/sh

# must work with "set -e"

foo ()
{
    echo foo: -$1-$2-$3-
    return 0
}

# only runs if there are parameters
# exits
main ()
{
    local cmd="$1"
    shift
    local rc=0
    $cmd "$@" || rc=$?
    exit $rc
}

if [[ "$*" ]]
then
    main "$@"
    die "how did we get here?"
fi

回答1:

You can get a list of functions in your script by using the grep command on your own script. In order for this approach to work, you will need to structure your functions a certain way so grep can find them. Here is a sample:

$ cat my.sh
#!/bin/sh

function func1() # Short description
{
    echo func1 parameters: $1 $2
}

function func2() # Short description
{
    echo func2 parameters: $1 $2
}

function help() # Show a list of functions
{
    grep "^function" $0
}

if [ "_$1" = "_" ]; then
    help
else
    "$@"
fi

Here is an interactive demo:

$ my.sh 
function func1() # Short description
function func2() # Short description
function help() # Show a list of functions


$ my.sh help
function func1() # Short description
function func2() # Short description
function help() # Show a list of functions


$ my.sh func1 a b
func1 parameters: a b

$ my.sh func2 x y
func2 parameters: x y

If you have "private" function that you don't want to show up in the help, then omit the "function" part:

my_private_function()
{
    # Do something
}


回答2:

typeset -f returns the functions with their bodies, so a simple awk script is used to pluck out the function names

f1 () { :; }
f2 () { :; }
f3 () { :; }
f4 () { :; }
help () {
    echo "functions available:"
    typeset -f | awk '/ \(\) $/ && !/^main / {print $1}'
}
main () { help; }
main

This script outputs:

functions available:
f1
f2
f3
f4
help


回答3:

You call this function with no arguments and it spits out a "whitespace" separated list of function names only.


function script.functions () {
    local fncs=`declare -F -p | cut -d " " -f 3`; # Get function list
    echo $fncs; # not quoted here to create shell "argument list" of funcs.
}

To load the functions into an array:


declare MyVar=($(script.functions));

Of course, common sense dictates that any functions that haven't been sourced into the current file before this is called will not show up in the list.

To Make the list read-only and available for export to other scripts called by this script:


declare -rx MyVar=($(script.functions));

To print the entire list as newline separated:


printf "%s\n" "${MyVar[@]}";


回答4:

The best thing to do is make an array (you are using bash) that contains functions that you want to advertise and have your help function iterate over and print them.

Calling set alone will produce the functions, but in their entirety. You'd still have to parse that looking for things ending in () to get the proverbial symbols.

Its also probably saner to use something like getopt to turn --function-name into function_name with arguments. But, well, sane is relative and you have not posted code :)

Your other option is to create a loadable for bash (a fork of set) that accomplishes this. Honestly, I'd prefer going with parsing before writing a loadable for this task.



标签: linux shell sh