Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
up vote 3 down vote accepted

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

share|improve this answer

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")
share|improve this answer
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 posting your answer, you agree to the privacy policy and terms of service.

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