Try the following simple one-liners:
For all UNIX/OSX/Linux
dir="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"
Bash
dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
Note: A double dash (--) is used in commands to signify the end of command options, so files containing dashes or other special characters won't break the command.
Note: In Bash, use ${BASH_SOURCE[0]}
in favor of $0
, otherwise the path can break when sourcing it (source
/.
).
*For Linux, Mac and other BSD:
cd "$(dirname "$(realpath -- "$0")")";
Note: realpath
should be installed in the most popular Linux distribution by default (like Ubuntu), but in some it can be missing, so you have to install it.
Note: If you're using Bash, use ${BASH_SOURCE[0]}
in favor of $0
, otherwise the path can break when sourcing it (source
/.
).
Otherwise you could try something like that (it will use the first existing tool):
cd "$(dirname "$(readlink -f -- "$0" || realpath -- "$0")")"
For Linux specific:
cd "$(dirname "$(readlink -f -- "$0")")"
*Using GNU readlink on BSD/Mac:
cd "$(dirname "$(greadlink -f -- "$0")")"
Note: You need to have coreutils
installed
(e.g. 1. Install Homebrew, 2. brew install coreutils
).
In bash
In bash you can use Parameter Expansions to achieve that, like:
cd "${0%/*}"
but it doesn't work if the script is run from the same directory.
Alternatively you can define the following function in bash:
realpath () {
[[ "$1" = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
This function takes 1 argument. If argument has already absolute path, print it as it is, otherwise print $PWD
variable + filename argument (without ./
prefix).
or here is the version taken from Debian .bashrc
file:
function realpath()
{
f=$@
if [ -d "$f" ]; then
base=""
dir="$f"
else
base="/$(basename -- "$f")"
dir="$(dirname -- "$f")"
fi
dir="$(cd -- "$dir" && /bin/pwd)"
echo "$dir$base"
}
Related:
See also:
How can I get the behavior of GNU's readlink -f on a Mac?
myscript path/to/file
I expect the script to evaluate path/to/file relative to MY current directory, not whatever directory the script happens to be located in. Also, what would you have happen for a script run withssh remotehost bash < ./myscript
as the BASH FAQ mentions? – Outboundcd "${BASH_SOURCE%/*}" || exit
– Appendicectomy