Skip to main content
1 of 3
it-alien
  • 460
  • 6
  • 10

TL;DR I'd recommend using ${BASH_SOURCE:-$0} as the most universal variant.

Previous answers are good but they do not mention one caveat of using ${BASH_SOURCE[0]} directly: if you invoke the script as sh's argument and your sh is not aliased to bash (in my case, on Ubuntu 16.04.5 LTS, it was linked to dash), it may fail with BASH_SOURCE variable being empty/undefined. Here's an example:

t.sh:

#!/usr/bin/env bash

echo "\$0:                    [$0]"
echo "\$BASH_SOURCE:          [$BASH_SOURCE]"
echo "\$BASH_SOURCE or \$0:    [${BASH_SOURCE:-$0}]"
echo "\$BASH_SOURCE[0] or \$0: [${BASH_SOURCE[0]:-$0}]"

(Successful) runs:

$ ./t.sh
$0:                    [./t.sh]
$BASH_SOURCE:          [./t.sh]
$BASH_SOURCE or $0:    [./t.sh]
$BASH_SOURCE[0] or $0: [./t.sh]

$ source ./t.sh
$0:                    [/bin/bash]
$BASH_SOURCE:          [./t.sh]
$BASH_SOURCE or $0:    [./t.sh]
$BASH_SOURCE[0] or $0: [./t.sh]

$ bash t.sh
$0:                    [t.sh]
$BASH_SOURCE:          [t.sh]
$BASH_SOURCE or $0:    [t.sh]
$BASH_SOURCE[0] or $0: [t.sh]

And finally:

$ sh t.sh
$0:                    [t.sh]
$BASH_SOURCE:          []
$BASH_SOURCE or $0:    [t.sh]
t.sh: 6: t.sh: Bad substitution

Resume

As you see, only the third variant: ${BASH_SOURCE:-$0} - works and gives consistent result under all invocation scenarios. Note that we take advantage of bash's feature of making a reference to an unsuscripted array variable equal to the first array element.

it-alien
  • 460
  • 6
  • 10