Get canonical value of relative path from bash script

bash

I've been using a command like the following to get the directory of a particular script when it is executed, regardless of where it was executed from:

MYDIR=$(dirname $(readlink -f $0))

What would be the similar one liner to get the canonical path for the directory that is two parents above the script directory? I have tried things like:

MYDIR=$(dirname $(readlink -f $0/../..))
MYDIR=$(readlink -f $(dirname $(readlink -f $0)/../..))

I'm not a bash guru, as you can tell. How would I do this?

Best Answer

You need to give /../.. to the last readlink, not to dirname:

$(readlink -f "$(dirname "$(readlink -f "$0")")/../..")

Your script causes dirname path/to/script/../.. to be executed, outputting "path/to/script/..", which readlink refuses to canonicalize because constructs such as file/.. are invalid in Linux and the -f option requires all components to exist. (readlink -m would work, since it does not check for existence of any path components.)

Related Question