How do you list all functions and aliases in a specific script?
The usual way is to use declare -f
which will print a very long list of functions in an interactive bash shell. But inside an script, as most external functions are not defined, the list will be short and useful.
So:
declare -f
Will list functions (and definitions). And:
declare -F
will print a list of name functions only.
There is a (not so easy to use) option of extdebug
which if set, the line numbers of the definition of each function will also be printed by declare -F
. But extdebug
needs to be set at script loading time (as all lines need to be known to be able to list them).
In general, it's impossible to list all functions without executing the script, because a function could be declared by something like eval $(/some/program)
. But if the functions are declared “normally”, you can search for things that look like function definitions.
grep -E '^[[:space:]]*([[:alnum:]_]+[[:space:]]*\(\)|function[[:space:]]+[[:alnum:]_]+)' myscript
There's no function typing or documentation facility in shell scripts, so any documentation would have to come from comments. Here's a crude Perl snippet that extracts commonly-formatted function definitions as well as immediately preceding or succeeding comments.
perl -0777 -ne '
while (/^((?:[ \t]*\#.*\n)*) # preceding comments
[ \t]*(?:(\w+)[ \t]*\(\)| # foo ()
function[ \t]+(\w+).*) # function foo
((?:\n[ \t]+\#.*)*) # following comments
/mgx) {
$name = "$2$3";
$comments = "$1$4";
$comments =~ s/^[ \t]*#+/#/mg;
chomp($comments);
print "$name\n$comments\n";
}' myscript
A more precise way to print function names, if you can run the script without causing any side effects, or if you can isolate all function definitions in a subscript, is to run the script and then make bash print out all the function definitions. Unlike the text search method above, this includes weirdly-formatted function definitions and excludes false positives (e.g. in here documents), but this cannot find comments.
bash -c '. myscript; typeset -f'
declare -F | awk '{print $NF}' | sort | egrep -v "^_"