Get a list of function names in a shell script
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
}
How do I list the functions defined in my shell?
declare -F
Function names and definitions may be listed with the
-f
option to the
declare
builtin command (see Bash Builtins). The-F
option todeclare
will list the function names only
(and optionally the source file and line number).
Bash Reference Manual
How would one get a list of functions in a shell script?
I assume bash is the shell.
typeset (or declare ) show the current environment, functions are part of the environment:
- there's no inherent ordering in the environment (names are sorted on output)
- the unwanted functions may be inherited from the environment, having been previously been
marked for export with declare -x
You could experiment with "env" to start your script in a clean environment, try:
env -i "PATH=$PATH" "TERM=$TERM" "LANG=$LANG" myscript.sh
as starting point.
The best way to enumerate functions in bash is documented here: Where is function's declaration in bash?
Note that "declare -F" does not normalise the filename, it will be as invoked/sourced.
while read xx yy fn; do
func=( $(shopt -s extdebug; declare -F $fn) )
printf "%-30s %4i %-30s\n" "${func[@]:2}" "${func[1]}" "${func[0]}"
done < <(declare -F)
All you need to do is filter by the required filename, and sort by line number.
How to determine function name from inside a function
You can use ${FUNCNAME[0]}
in bash
to get the function name.
Loop through array of function names and execute all of them in a bash script
You get this error because you didn't quote your variables. Therefore test a
is split into two parts.
Try it like this:
#!/bin/bash
functions_array=("test a" "test b" "testc")
test() {
echo "$1" # quoting here and ...
}
testc() { echo "testc!"; }
for i in "${functions_array[@]}"; do # also here
${i}
done
Listing defined functions in Bash
How about compgen:
compgen -A function # compgen is a shell builtin
List bash functions and locations
The documentation does not clearly say that, but you need to call declare -F
with a particular function as argument in order to obtain the file and line number of it's declaration. It can be done in a loop:
$ shopt -s extdebug
$ declare -F | while read foo bar fun ; do declare -F "$fun" ;done
$ shopt -u extdebug
How to get script name inside function in shell script?
As I commented, your scripts won't even do what you claimed it does:
this is unlikely. you did not show everything. in bash, functions are not exportable, therefore sourcing script2 in script1 won't make logger visible in script3. you must have done something in script3.
Indeed, copying your code and run it locally indicates what's happening:
$ ./script1.sh
++ echo 'This is script1'
This is script1
++ source script2.sh
++ sh script3.sh
+ echo Script3 start
Script3 start
+ log
script3.sh: 3: script3.sh: log: not found
+ echo End of script3
End of script3
++ echo 'End of script1'
End of script1
notice the command not found error, which is exactly what I thought.
In fact, if you check bash's manual properly, there is a proper way of achieving what you want exactly:
BASH_SOURCE
An array variable whose members are the source filenames where the corresponding shell function names in the FUNCNAME array variable are defined. The shell function
${FUNCNAME[$i]} is defined in the file ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}.
read it carefully, it says function defined from ${BASH_SOURCE[$i]}
and called from ${BASH_SOURCE[$i+1]}
. In this case, logger
resides in ${BASH_SOURCE[0]}
, and the caller simply resides in ${BASH_SOURCE[1]}
.
therefore, change your script2
to following shall work:
$ cat script2.sh
log(){
echo "The calling script name is ${BASH_SOURCE[1]}"
}
(except I changed the function name so that it does not collide with my other shell tool.)
demo:
$ ./script1.sh
This is script1
Script3 start
The calling script name is ./script3.sh
End of script3
End of script1
indeed does the work.
Finding main functions' names in a C file via Bash script
If I understand your specifications correctly this should do it:
root@local [~]# awk '/^[ \t]*(int|float|double)[ \t]+ksz_/ {print $2}' sample.txt
One thing I did not understand was whether there should only be one "_" after ksz so for example if "double ksz_Input_Helper1" is not something you want to match. In the regex above it does match.
I also chose to go with awk rather than grep as you said you want only the name the above awk prints only the second field using whitespace as a delimiter. If you still want to use grep this one does the same task:
root@local [~]# egrep '^\s*(int|float|double)\s+ksz_' sample.txt
Here is a breakdown(note in awk I use [ \t] in place of \s as I could not get it to recognize \s]:
^ - match start of line
\s* - match if there are 0 or more white spaces
(int|float|double) - match int, float, OR double
\s+ - match at least one whitespace
ksz_ - match literal string "ksz_"
Related Topics
Why Is Pr_Debug of the Linux Kernel Not Giving Any Output
Using Named Pipes with Bash - Problem with Data Loss
Microsecond Accurate (Or Better) Process Timing in Linux
Linux Command Output as a Parameter of Another Command
How to Use Awk to Convert All the Lower-Case Letters into Upper-Case
What Does "|" Mean in a Terminal Command Line
Force Gnu Linker to Generate 32 Bit Elf Executables
What Scheduling Algorithms Does Linux Kernel Use
Cpu Affinity Masks (Putting Threads on Different Cpus)
How Is Stack Size of Linux Process Related to Pthread, Fork and Exec
Differencebetween Alpine Docker Image and Busybox Docker Image
Accessing .So Libraries Using Dlopen() Throws Undefined Symbol Error
Git Permission Denied (Publickey,Gssapi-Keyex,Gssapi-With-Mic)
Understanding Buffers/Cache in Linux 'Free -M'
How to Test If an Address Is Readable in Linux Userspace App
Why Do I Have to 'Wait()' for Child Processes
Use Sed to Delete All Leading/Following Blank Spaces in a Text File