Behavior of cd/bash on symbolic links

Hermann Speiche picture Hermann Speiche · May 5, 2012 · Viewed 10.3k times · Source

Assume I have the folders ~/a/b in my home folder, and the folder b contains a symbolic link to '..' named 'symlink'. Then I perform the following actions in bash:

hm@mach:~$ cd a/b/symlink
hm@mach:~/a/b/symlink$ pwd -P
/home/hm/a
hm@mach:~/a/b/symlink$ cd ..
hm@mach:~/a/b$ pwd -P
/home/hm/a/b

pwd -P prints the current working directory, dereferencing all symbolic links. Why is the working directory /home/hm/a/b at the end, and not /home/hm?

Answer

sarnold picture sarnold · May 5, 2012

According to help cd,

  Options:
      -L        force symbolic links to be followed: resolve symbolic
                links in DIR after processing instances of `..'
      -P        use the physical directory structure without following
                symbolic links: resolve symbolic links in DIR before
                processing instances of `..'

In other words, -L means using the logical structure, whereas -P uses the actually physical directory structure.

The logical structure is like this,

$ tree a
a
└── b
    └── symlink -> ..

The actual physical structure when you go to a/b/symlink is,

a

If you want to use the real .., then you must also use cd -P:

          The -P option says to use the physical directory
          structure instead of following symbolic links (see
          also the -P option to the set builtin command);
          the -L option forces symbolic links to be followed.

An example,

$ cd
$ cd a/b/symlink   # physical location is at a/
$ cd ..            # now is at a/b
$ cd symlink       # goes back to a/b/symlink
$ cd -P ..         # follow physical path (resolve all symlinks)
$ pwd -P           # -P is optional here to show effect of cd ..
/home/sarnold
$