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
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • I'm sorry, could you describe what you expected to happen in the second example please? – Kusalananda Mar 07 '18 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. – Tim Kennedy Mar 07 '18 at 16:44
  • I expected it to follow the logical structure and thus try to change to /home/hexcabron/test/d/e and fail. –  Mar 07 '18 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. http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11 – Tim Kennedy Mar 07 '18 at 16:59
  • @Tim: Shouldn't the cd in the first example then also have followed the path as a directory (= physical, not logical), leading to cd /home/hexcabron/test/a/a and fail? –  Mar 07 '18 at 17:15
  • Ah, yes. I missed the double ... Also, I just tried your setup at home, and on my Ubuntu system, I am unable to duplicate your behavior. If I cd symlink, pwd shows me test/d/symlink, and cd symlink/.. sends me back to test/d. – Tim Kennedy Mar 07 '18 at 17:43
  • 1
    A related question is https://unix.stackexchange.com/questions/413204/ . – JdeBP Mar 07 '18 at 21:13

1 Answers1

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

John Moon
  • 1,013