Akramat
Akramat

Reputation: 51

Why is the double dot(parent directory) acting weird with the bin folder?

I started studying bash from the very beginning. I decided to practice using shortcuts for the current directory and the parent directory (dot and double dot). I noticed some strange behavior of the latter with the bin folder. To show this strangeness, I will first show how it works with home directory, and then how it works with bin.

  1. Let's output the contents of the root folder result of command ls /
  2. I start practicing. We go to the home folder, then back, and it turns out to be the root folder again.(Works as expected)result of command ls /home/..
  3. But for some reason the same thing doesn't work with the Bin folder. It does not show the contents of the root directory, as in the cases above. result of command ls /bin/.. EDT: I've tried 'cd bin/..' and 'cd bin/../..' and in both cases 'pwd' says i'm in '/', but why is ls's output diffent?
  4. And to make it work you have to go back twice.result of command ls /bin/../..

Like the home directory, directories etc, mnt, boot work correctly. But bin does not. Can someone explain why this is?

Upvotes: 2

Views: 79

Answers (1)

chrslg
chrslg

Reputation: 13491

/bin is probably a symbolic link to /usr/bin. At least it is a link to somewhere. But since I know some unix system have /bin be a symlink to /usr/bin, plus the fact that the content of your displayed /bin/.. is the same as /usr on my machine (on which there is no such symlink tho, but on my previous arch, there was).

So, have a look at ls -ld /bin

You'll see that it is a link to /usr/bin or to ../usr/bin. So /bin/.. is really /usr/bin/.. that is /usr

Just an experiment

(An experiment to show that this would be exactly what happen if /bin was a symlink to /usr/bin)

Set up some mock tree (I use capital for directories, and touch a file that shows full (full from my mock root Tmp) path each dir)

mkdir Tmp
touch Tmp/root
mkdir Tmp/Usr
touch Tmp/Usr/usr
mkdir Tmp/Usr/Bin
touch Tmp/Usr/Bin/usr.bin
cd Tmp
ln -s Usr/Bin Bin
cd ..

From there we can see that

ls -ld Tmp/Bin

is a link (obviously, since I made it that way. Just since you discover all that, want to make clear that this is what your saw on your actual system) : Tmp/Bin -> Usr/Bin

And therefore that

ls Tmp/Bin/..

shows

Bin  usr

That is the content of Tmp/Usr, not the one of Tmp (that would be root)

cd different behaviour

But, indeed

cd Tmp/bin/..
ls

shows

Bin  root  Usr

That is the content of Tmp not Tmp/Usr, as if Tmp/Bin parent were Tmp

why ?

As for why, it is important to understand that cd is not a program (unlike ls, cp, etc.). It is a shell command. So it can have a different (in this case, documented), behaviour. Well, theoretically, any program can have its own interpretation of those ..; what they are passed is just a string, such as bin/.., what they do with it, is up to them. But most would do just a open or opendir , with that string argument, and that would lead bin/.. to be interpreted as you have seen ls do.

cd acts differently, as the documentation says (man bash)

If .. appears in dir, it is processed by removing the immediately previous pathname component from dir

In other words, cd foo/bar/bla/.. means cd foo/bar whatever those are in reality. Especially, if bla is a symlink to a different place far for foo/bar, it doesn't matter. cd process first, transparently, without even caring what the filesystem have to say about those (or even if they make any sense from the filesystum point of view. It is just some string processing), is to remove any .. and what immediately precedes it, from the chain of / separated substring. And then, and only then, it starts to bother with reality of filesystem.

You can force it, tho, to act as another command would do, that is to resolve what is really foo/bar/bla/.. or Tmp/Bin/.. or /bin/.., by using option -P

The -P option causes cd to use the physical directory structure by resolving symbolic links while traversing dir and before processing instances of .. in dir

cd -P Tmp/Bin/..
ls

shows indeed

Bin  usr

as you were expecting (that is what ls Tmp/Bin/.. would show

Ok but why ?

Lastly, the reason of that choice from cd, frankly I have no idea. What I know is that unix system call chdir (man 2 chdir) does behave like the bash command with -P flag. So reason is not a Unix reason. More a bash choice.

For example, tcsh (another shell. The one that was quite standard when I learned Unix, and still exists today) acts differently

$ tcsh
> cd Tmp/Bin/..
> ls

shows

Bin  usr

(Note that I use ls and my touched files to know where cd goes. Obviously pwd is the tool to know where I am. I do so only because your initial question was about ls)

So, different shells, different behavior. This is not a Unix thing, but a bash thing (and sh, and zsh, ...)

Upvotes: 5

Related Questions