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 to get the content of a function in a string using bash?
Make a dummy function foo(), which just prints "bar":
foo() { echo bar ; }
Now a bash
function to print what's in one (or more) functions. Since the contents of a function are indented with 4 spaces, sed
removes any lines without 4 leading spaces, then removes the leading spaces as well, and adds a ';' at the end of each function:
# Usage: in_func <function_name1> [ ...<function_name2> ... ]
in_func()
{ while [ "$1" ] ; do \
type $1 | sed -n '/^ /{s/^ //p}' | sed '$s/.*/&;/' ; shift ; \
done ; }
Print what's in foo():
in_func foo
Output:
echo bar;
Assign what's in foo() to the string $baz, then print $baz:
baz="`in_func foo`" ; echo $baz
Output:
echo bar;
Run what's in foo():
eval "$baz"
Output:
bar
Assign what's in foo() to $baz three times, and run it:
baz="`in_func foo foo foo`" ; eval "$baz"
Output:
bar
bar
bar
How to determine function name from inside a function
You can use ${FUNCNAME[0]}
in bash
to get the function name.
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
}
Listing defined functions in Bash
How about compgen:
compgen -A function # compgen is a shell builtin
Can't detect whether a shell function is defined from a script
Unless they've been exported with export -f
, functions are local to a single instance of the shell. Your script runs in a different instance.
If you want your command to be able to determine which shell functions are active, you should either write it to be sourced into an existing shell rather than executed as an external command, or define it as a shell function itself.
You could also source in .bashrc
, if you're willing to deal with your script's behavior being modified by its side effects:
brc="$HOME/.bashrc"
[[ -e "$brc" ]] && source "$brc"
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.
bash script building a find command that contains \n
First -- code generation in bash is for experts only, and carries serious security risks. Consider finding a different way to suit your needs.
That being said, the following behaves as-intended:
#!/usr/bin/env bash
checkShellCompat() {
[ -n "$BASH_VERSION" ] && return
echo "ERROR: Must run this script with bash, not sh" >&2
exit 1
}
buildFindCmds() {
# generate a correct shebang, and run the shell compatibility check
printf '%s\n' '#!/usr/bin/env bash' "$(declare -f checkShellCompat)" checkShellCompat
# ...then, for each directory, generate a find command with a correct redirection
for dir; do
printf '%q ' find "./$dir" -printf '%f\n'
printf '>%q\n' "${dir}filelist.txt"
done
}
buildFindCmds 201911 201912
Related Topics
Command Not Found When Using Sudo
What Happens If There Is No Exit System Call in an Assembly Program
How to Install Latest Version of Git on Centos 8.X/7.X/6.X
Difference Between Using 'Sh' and 'Source'
Find Multiple Files and Rename Them in Linux
What Is Better "Int 0X80" or "Syscall" in 32-Bit Code on Linux
Calling Printf in X86_64 Using Gnu Assembler
How Many Socket Connections Possible
Is There a "Goto" Statement in Bash
Bash While Read Loop Extremely Slow Compared to Cat, Why
How to Run a Shell Script When a File or Directory Changes
Why Does a Jvm Report More Committed Memory Than the Linux Process Resident Set Size
How Are the Fs/Gs Registers Used in Linux Amd64
Expanding a Bash Array Only Gives the First Element
How to Send a HTML Email With the Bash Command "Sendmail"