Leo Jiang Leo Jiang - 2 months ago 9
Linux Question

Two seemingly equivalent paths in Linux, one works and one doesn't

I'm in directory

~/www
and I'm trying to edit
~/.bashrc
.

I did
vi ../.bashrc
and Vim creates a new empty file.

I did
cd ..
and
vi .bashrc
and the correct file is opened.

Is this supposed to happen in Linux?

Edit:
I just tried
touch ../.bashrc
in
~/www
and I can't find the file that should've been created.

Answer

This will happen if the current directory is a symlink.

When you cd to a symlink, .. will refer to the symlink target's parent:

$ ln -s /tmp mylink
$ cd mylink
$ pwd
/home/me/mylink
$ realpath .
/tmp
$ realpath ..
/

However, bash will confuse you by being clever and have cd .. behave differently. Here's help cd:

`..' is processed by removing the immediately previous pathname component back to a slash or the beginning of DIR.

This means that when you cd .., bash will magically take you from /home/me/mylink to /home/me. This difference is very confusing, but also very useful.

If you use cd -P .., this magic is not invoked, and it will take you from /home/me/mylink to /, just like all other tools would.


This is easier when you realize that .. is not in any way special syntax that means "parent directory". Every directory actually has an honest-to-Linus entry named ..

On older Unix systems, this was just a convenient convention, and mkdir /foo/bar would also automatically ln /foo /foo/bar/.. which you could delete or relink as you wanted. Today, it is instead strictly enforced by the file system.

Obviously, /tmp/.. links to /, and that doesn't change just because you followed a symlink to get to /tmp.