Find -Exec' a Shell Function in Linux

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 to declare
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



Leave a reply



Submit