Bash – Sourcing a script containing `echo ${BASH_SOURCE[0]}` still shows the pathname of the sourced script

bashsource

I have a bash script, which outputs the pathname of the script itself

$ cat f4.sh 
#! /bin/bash    
echo "${BASH_SOURCE[0]}"

I imagine that if I source the script in another script and run the other script, it will output the pathname of the other script, because sourcing is like copy the content of the sourced script into the the sourcing script and run the sourcing script.

But I am wrong, and it still outputs the pathname of the original script

$ cat ff.sh 
#! /bin/bash
source ../f4.sh

$ bash ff.sh 
../f4.sh

Why?

I was wondering if it is possible for another script to output its pathname by using f4.sh instead of directly using ${BASH_SOURCE[0]}? Thanks.

Best Answer

In this situation, if you had wanted to get the main script's pathname from BASH_SOURCE, you would have had to use ${BASH_SOURCE[1]}.

For each level of sourcing, a new element is added to the beginning of the BASH_SOURCE array, so that ${BASH_SOURCE[0]} is always the current source file and ${BASH_SOURCE[1]} the one that it was sourced from (and ${BASH_SOURCE[2]} the one that it was sourced from, if it was sourced). To get at the main script, look at ${BASH_SOURCE[-1]}, the last element.

Sourcing a script does not quite copy the content of the script into the main script. It is like running an ordinary script, but it executes in the same environment as the main script. It's more akin to executing a function.

Related Question