Djeah
Djeah

Reputation: 360

How to get script name inside function in shell script?

I have three scripts:

Contents of my script:

script1.sh:

echo"This is script1"
source script2.sh
sh script3.sh
echo "End of script1"

script2.sh:

logger(){
 echo "The calling script name is $BASH_SOURCE"
}

script3.sh:

echo "Script3 start"
logger
echo "End of script3"

When I run sh script1.sh, I want the logger function to print

script3.sh

because that is the script which is calling the function. But instead, it is printing

script2.sh

Is there any way to do this?

Upvotes: 4

Views: 2421

Answers (1)

Jason Hu
Jason Hu

Reputation: 6333

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.

Upvotes: 6

Related Questions