Exploring the BASH_SOURCE Array
$BASH_SOURCE
is the call stack of scripts with the top of the stack being the currently executing sourced script, sourcing another script from the current one will push it on top of the stack. To get an idea of how this works you can set up a directory tree to provide a variety of ways to call the same script:
cd /tmp
mkdir -p 1/2/3/4/5/6/7/8/9/0
vim 1/2/3/4/5/6/7/8/9/0/bash_source.sh
Inside the script we'll print out the contents of the $BASH_SOURCE
array for the current invocation and then if the array isn't too long already we'll recursively call the script again from further down the directory tree:
#!/bin/bash
for I in $(seq 0 $(expr ${#BASH_SOURCE[@]} - 1) ); do
echo BASH_SOURCE\[$I\] ${BASH_SOURCE[$I]}
done
echo
if [[ ${#BASH_SOURCE[@]} -le 10 ]]; then
cd [0-9] # head up a directory
. ${BASH_SOURCE[0]#[0-9]/} # call top of the stack, minus leading directory
fi
And this is what you end up with. Initially the $BASH_SOURCE
array is just the initial invocation, but with further recursive sourcing it continues to grow:
./1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[1] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[1] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[2] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[1] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[2] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[3] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[1] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[2] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[3] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[4] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[1] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[2] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[3] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[4] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[5] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 7/8/9/0/bash_source.sh
BASH_SOURCE[1] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[2] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[3] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[4] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[5] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[6] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 8/9/0/bash_source.sh
BASH_SOURCE[1] 7/8/9/0/bash_source.sh
BASH_SOURCE[2] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[3] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[4] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[5] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[6] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[7] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 9/0/bash_source.sh
BASH_SOURCE[1] 8/9/0/bash_source.sh
BASH_SOURCE[2] 7/8/9/0/bash_source.sh
BASH_SOURCE[3] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[4] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[5] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[6] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[7] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[8] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] 0/bash_source.sh
BASH_SOURCE[1] 9/0/bash_source.sh
BASH_SOURCE[2] 8/9/0/bash_source.sh
BASH_SOURCE[3] 7/8/9/0/bash_source.sh
BASH_SOURCE[4] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[5] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[6] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[7] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[8] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[9] 1/2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[0] bash_source.sh
BASH_SOURCE[1] 0/bash_source.sh
BASH_SOURCE[2] 9/0/bash_source.sh
BASH_SOURCE[3] 8/9/0/bash_source.sh
BASH_SOURCE[4] 7/8/9/0/bash_source.sh
BASH_SOURCE[5] 6/7/8/9/0/bash_source.sh
BASH_SOURCE[6] 5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[7] 4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[8] 3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[9] 2/3/4/5/6/7/8/9/0/bash_source.sh
BASH_SOURCE[10] 1/2/3/4/5/6/7/8/9/0/bash_source.sh