Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

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


   +- somedir/
   +- symlink/  -> /some_other_dir

This command (in addition to my Makefiles) fails:

cd /base/symlink
ls ../somedir

Bash complains that ../somedir does not exist. Likewise, my makefiles in some_other_dir that reference ../somedir fail. However, cd .. works just as expected. Can I have my shell act with regards to the logical structure?

share|improve this question
You mean cd ../somedir works, while ls ../somedir does not, right? I could reproduce this behavior. – Bernhard Jan 16 '13 at 15:11
@Bernhard: that is correct. This also breaks some more complex commands in my Makefile. – Atilla Filiz Jan 16 '13 at 15:46
sure you don't have a broken symlink. This workflow fine on my system. Did I get your example correct? [code] /tmp # ls -ld {bob,tom} drwxr-xr-x 3 scott scott 4.0K Jan 16 12:29 bob lrwxrwxrwx 1 scott scott 3 Jan 16 12:29 tom -> bob /tmp # cd tom /tmp/tom # ls dir file /tmp/tom # ls ../bob dir file [/code] – frogstarr78 Jan 16 '13 at 20:32
up vote 7 down vote accepted

.. is a directory entry in the current directory. It is a hardlink to the directory one level up. /base/symlink/.. is actually the same file as /some_other_dir/.., and it is / (unless some_other_dir is itself also a symlink to somewhere else).

In most shells, cd treats .. specially, that is instead of treating it as the .. directory entry, occurrences of .. are interpreted by cd (and not by the system's pathname resolution) as removing one level of directory.

As an example, in cd a/b/.., the shell does a chdir("a") instead of doing a chdir("a/b/.."). To get the latter, you need to do cd -P a/b/...

It's important to realise that it only applies to cd (and only in some shells), (IMO, a misfeature), not to ls or vi or anything else (unless that anything else is a script written with those shells).

In those shells where cd does that logical interpretation of .., the pwd builtin and the $PWD variable contain the logical current directory instead of the real (physical) one, that is one with possibly symlink directory components. Similarly, you can use pwd -P to get the physical working directory.

Now, if you want to do

cd /A/b
anything-but-cd ../c

And actually mean:

anything-but-cd /A/c

Regardless of whether /A/b was a symlink or not, you could do instead:

anything-but-cd "$(dirname -- "$PWD")/c"


anything-but-cd "${PWD%/*}/c"
share|improve this answer

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.