Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
add comment

2 Answers

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
add comment

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

#!/bin/bash

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

# 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
add comment

Your Answer

 
discard

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.