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?