6

Drectories contain . and .. which are hard links to the current and parent directory.

So how does the shell know for example in the prompt, that the current directory is called "a" in cd a/path/..? Does it have special casing for this?

Otherwise from its perspective, isn't it entering a directory called .., rather than knowing that this directory is also the directory above? How does it know the name?

James
  • 61
  • ls -a if you look then both . and .. exist in the current directory. –  May 07 '15 at 11:57
  • 3
    The directory entry .. refers to the parent directory. To change to the 'previous' directory you can use cd - – Lambert May 07 '15 at 12:00
  • @Lambert What does that have to do with the question ? –  May 07 '15 at 12:03
  • 2
    @JID, I hope it clarifies that .. is not a hardlink to the previous directory as stated by James. – Lambert May 07 '15 at 12:04
  • 1
    @Lambert he obviously meant the parent, don't be pedantic. –  May 07 '15 at 12:05
  • 1
    @JID the details matter, I think the pedantry is warranted. – pdo May 07 '15 at 12:49
  • @ChrisDown That is the most confusing sentence i have ever read. –  May 07 '15 at 12:58
  • @pdo The context was enough to understand, it was unnescesary to answer the question. –  May 07 '15 at 12:59
  • @OP This may help you understand http://www.slashroot.in/inode-and-its-structure-linux –  May 07 '15 at 12:59
  • @JID In which case, allow me to try again: I think the question is asking about the following: cd foo/bar; cd .. -- this results in the shell stating the directory is "foo" in the prompt, but how does it know that cd .. went to the same directory as "foo"? – Chris Down May 07 '15 at 13:04
  • @ChrisDown Look at my link –  May 07 '15 at 13:05
  • 1
    @JID Do you have a specific part that you want the OP to look at? inodes don't store name information -- the answer doesn't lie there. While cd .. doesn't need to know any name information, the shell does have to take some special casing to know that .. == foo. – Chris Down May 07 '15 at 13:11
  • @ChrisDown Yes it uses the inode instead,both foo and .. have the same inode, did you even read what i linked? Read the bit that says Inode Structure of a Directory: –  May 07 '15 at 13:14
  • @JID I'm quite aware of how an inode works, thanks. Yes, they have the same inode, but there is no inode -> file mapping present in the filesystem, only file -> inode. As such, special casing is needed. – Chris Down May 07 '15 at 13:16
  • @ChrisDown clearly you don't –  May 07 '15 at 13:16
  • 1
    You might find these interesting: http://unix.stackexchange.com/a/79621 and http://unix.stackexchange.com/a/61513 – Stéphane Chazelas May 07 '15 at 14:46

2 Answers2

4

I assume that your question is how bash can know to change the directory so that the working directory is foo (rather than foo/bar/..) in cd foo/bar/...

While these two paths will be are represented by the same inode (unless there are symlinks present in the path, as shown at the end of this answer), the shell does need to take special measures to show the current directory name as foo, rather than ... In bash, when cd encounters .. in the path, it internally just strips the parent directory away, meaning that .. can never be the directory name.

This is documented in help cd:

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

This special casing results in the following interesting behaviour (note that foo/qux/.. still resolved to foo, even when the real path was bar/baz/..):

$ tree
.
|-- bar
|   `-- baz
`-- foo

3 directories, 0 files
$ ln -s "$(readlink -f bar/baz)" foo/qux
$ tree
.
|-- bar
|   `-- baz
`-- foo
    `-- qux -> bar/baz

4 directories, 0 files
$ cd foo/qux/..
$ basename "$(pwd)"
foo
Chris Down
  • 125,559
  • 25
  • 270
  • 266
  • foo/bar/.. is foo, they have the same inode. It has absolutely nothing to do with cd. Any command will work.Try ls -id foo/bar/.. and ls -id .. It uses the inode and the inode is the same. –  May 07 '15 at 13:29
  • 1
    @JID I think you're missing the point of the question being asked -- foo/bar/.. and foo are the same inode, but they are not the same path. The shell has to make special considerations to declare the path as foo rather than foo/bar/... – Chris Down May 07 '15 at 13:30
  • It doesn't have to make any considerations, it just gets the inode for whatever you call, the filenames/directories are just for the user to look at. –  May 07 '15 at 13:32
  • 1
    @JID That's the point -- the filename being presented to the user by the shell is not .., but foo, and the shell can only know that this is so by special casing. The shell does have to special case finding the filename for the user to look at from somewhere, as there's no inode -> filename mapping, only filename -> inode. – Chris Down May 07 '15 at 13:33
  • RIghtttt, i think i understand what you are saying now,I interperet the question differently, as in How does it know where to go, rather than how does it get the name. But you have answered purely in the context of how cd changes PWD,etc. But yeah I understand what you're saying now :)Would have been nice for OP to have given some clarification or any comment at all ! –  May 07 '15 at 13:40
  • 1
    foo/bar/.. and foo may not be the same inode if foo or foo/bar are symlinks. – Stéphane Chazelas May 07 '15 at 14:43
  • @StéphaneChazelas Thanks for your note! I'd neglected to think about that, I've added it to my answer. – Chris Down May 07 '15 at 14:51
1

As you said, .. is a hard link to the parent directory. The shell does not need to know the name of the directory when accessing ..; it simply accesses the directory through the inode.

An inode is a structure that stores all metadata of the file (or directory), except the file's name: type, permissions, owner, group, size, access/change/modification/deletion times, number of links, attributes, ACLs, and address where the actual file content (i.e. the data) is stored.

dr_
  • 29,602
  • 3
    That's not true of cd (in most shells except the Bourne shell), that does a logical handling of .. regardless of the .. hard link. You need cd -P for cd to chdir into the .. directory. See http://unix.stackexchange.com/a/61513 – Stéphane Chazelas May 07 '15 at 14:41