1

I am currently trying understand the behavior of Bash's cd when it comes to symbolic links. By default, cd should follow the logical directory structure and should not resolve symbolic links.

cd behaves like this in my first example. However, I came up with a second example where cd seems to follow the physical structure. Is this expected behavior? What's the difference?

Setup

$ cd
$ mkdir -p test/a/b/c test/d
$ tree test
test
├── a
│   └── b
│       └── c
└── d

4 directories, 0 files
$ cd test/d
$ ln -s ../a/b/c symlink

1st example

$ pwd
/home/hexcabron/test/d
$ tree ..
..
├── a
│   └── b
│       └── c
└── d
    └── symlink -> ../a/b/c

5 directories, 0 files
$ cd symlink/../../a
$ pwd
/home/hexcabron/test/a

2nd example

$ cd ../d
$ pwd
/home/hexcabron/test/d
$ mkdir -p symlink/../e
$ tree ..
..
├── a
│   └── b
│       ├── c
│       └── e
└── d
    └── symlink -> ../a/b/c

6 directories, 0 files
$ cd symlink/../e
$ pwd
/home/hexcabron/test/a/b/e
7
  • I'm sorry, could you describe what you expected to happen in the second example please?
    – Kusalananda
    Commented Mar 7, 2018 at 16:22
  • I don't see any unexpected behavior there. symlink = test/a/b/c, so cd symlink/../e is the equivalent of cd test/a/b/c/../e, which is the equivalent of cd test/a/b/e. In fact, I don't even see any inconsistent behavior. In both your examples, the behavior is the same. Commented Mar 7, 2018 at 16:44
  • I expected it to follow the logical structure and thus try to change to /home/hexcabron/test/d/e and fail.
    – user279450
    Commented Mar 7, 2018 at 16:45
  • Ah. Once you put that trailing slash onto symlink so it's symlink/, that tells both mkdir and cd to follow that path as a directory, as long as it exists, and as long as it's not a loop of symlinks that point to each other more than 20 times (MAXSYMLINKS defined in bits/param.h) This is part of the POSIX specification around pathname resolution. opengroup.org/onlinepubs/009695399/basedefs/… Commented Mar 7, 2018 at 16:59
  • 1
    A related question is unix.stackexchange.com/questions/413204 .
    – JdeBP
    Commented Mar 7, 2018 at 21:13

1 Answer 1

1

Good question. Assuming you're using bash, cd will default to following symbolic links. This behavior can be overridden using the -P and -L flags which force cd to use the physical path and link path respectively.

I assume in your 1st example, cd noticed there was no path to directory a following the symlink, so it tried the physical path and found the directory. I can't easily find evidence to back up that assumption, but you could follow the logic in the source to see exactly what's going on (it's not that much code).

1
  • This guess is correct , the relevant source code logic bit starts here.
    – undercat
    Commented Mar 7, 2018 at 19:30