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?


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.)


For those who don't have readlink (like me on git bash)


function canonicalPath
    local path="$1" ; shift
    if [ -d "$path" ]
        echo "$(cd "$path" ; pwd)"
        local b=$(basename "$path")
        local p=$(dirname "$path")
        echo "$(cd "$p" ; pwd)/$b"

# usage example
mycanonicalpath=$(canonicalPath "$myrelativepath")
  • I think you may have forgotten to tie this into an answer to the question. It's a neat wrapper for turning pwd into something greater, though. Very unixy =) – Eroen Sep 13 '12 at 22:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.