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?

  • 3
    The directory entry .. refers to the parent directory. To change to the 'previous' directory you can use cd - – Lambert May 7 '15 at 12:00
  • 2
    @JID, I hope it clarifies that .. is not a hardlink to the previous directory as stated by James. – Lambert May 7 '15 at 12:04
  • 1
    @Lambert he obviously meant the parent, don't be pedantic. – user78605 May 7 '15 at 12:05
  • 1
    @JID the details matter, I think the pedantry is warranted. – pdo May 7 '15 at 12:49
  • 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 7 '15 at 13:11
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
  • 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. – user78605 May 7 '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 7 '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. – user78605 May 7 '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 7 '15 at 13:33
  • 1
    foo/bar/.. and foo may not be the same inode if foo or foo/bar are symlinks. – Stéphane Chazelas May 7 '15 at 14:43
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.

  • 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 unix.stackexchange.com/a/61513 – Stéphane Chazelas May 7 '15 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.