Reputation: 360
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
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