Here are different ways to obtain the realpath of the script. Each have their cons and pros and might have slight differences.
I am listing them here so overtime I can complete the list of cons and pros and what they actually do.
script_root=$(dirname $(readlink -f $0))
# Copyright http://stackoverflow.com/a/7400673/257479
myreadlink() { [ ! -h "$1" ] && echo "$1" || (local link="$(expr "$(command ls -ld -- "$1")" : '.*-> \(.*\)$')"; cd $(dirname $1); myreadlink "$link" | sed "s|^\([^/].*\)\$|$(dirname $1)/\1|"); }
whereis() { echo $1 | sed "s|^\([^/].*/.*\)|$(pwd)/\1|;s|^\([^/]*\)$|$(which -- $1)|;s|^$|$1|"; }
whereis_realpath() { local SCRIPT_PATH=$(whereis $1); myreadlink ${SCRIPT_PATH} | sed "s|^\([^/].*\)\$|$(dirname ${SCRIPT_PATH})/\1|"; }
script_root=$(dirname $(whereis_realpath "$0"))
(not reliable)
# Copyright https://stackoverflow.com/a/13222994/257479
script_root=$(ls -l /proc/$$/fd | grep "255 ->" | sed -e 's/^.\+-> //')
Update: I found an example where this snippet failed. Haven't investigated what the problem was yet.
Using
"$0"
withoutreadlink -f
would not allow to execute another script using relative path, if the script is called via a symlink.For example, here I am using
script_root
to source another bash script that contains functions that I need:. $script_root/inc/helpers.sh
This will break with
$(dirname "0")
if the script is called as a symlink.