To get a script's own directory, we recommend two options:
-
Option 1:
realpath
is more capable but not POSIX yet. -
Option 2:
cd
is POSIX yet less capable.
Code:
command -v realpath >/dev/null 2>&1 || printf realpath\\n 1>&2 && exit 69
dir=$(dirname "$(realpath "$0")")
The realpath
technique is a good solution if your system supports it.
-
Pros: Works when the script is run directly, or run via symlink, or sourced.
-
Cons: Not POSIX yet; it is on track to be added to the next POSIX update.
Details:
-
The
realpath
command is installed on many major operating systems on the current versions. The command is also able to be installed on older operating systems. -
The code
exit 69
is the exit number convention for "Unavailable: a service is unavailable. E.g. a support program or file does not exist."
To install realpath
on older macOS via brew:
brew install coreutils
Code:
dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
The cd
technique is POSIX and returns the directory of a running script.
Pros: POSIX, and works on a very wide range of systems, including much older systems.
Cons: Does not work if the script is invoked as a symlink, or if the script is sourced.
https://stackoverflow.com/questions/29832037/how-to-get-script-directory-in-posix-sh
The CDPATH=
is set to a null string so as to ensure that `cd`` never echoes anything.
The pwd -P
option is used to print the path with all symlinks resolved. This
resolves the resulting directory path to its ultimate target in case the
directory and/or its components are symlinks,
This code uses realpath if it's available, otherwise falls back to use cd:
if command -v realpath >/dev/null 2>&1; then
dir=$(dirname "$(realpath "$0")")
else
dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
fi
We do not want to use readlink -f
because it's not available on some operating systems, such as macOS. The option -f
is a GNU capability, and not POSIX.