How do pwd and . determine the current path differently

directorypwd

Is it mainly because pwd is not a builtin, while . is builtin to the bash shell?

For example, they differ in the following example:

/tmp/ttt$ mv ../ttt ../tttt
/tmp/ttt$ pwd
/tmp/ttt
/tmp/ttt$ cd .
/tmp/tttt$

Best Answer

. is not a bash (or any other shell) built-in. Each and every directory has entries . and .. in it. You can verify by cd'ing to some arbitrary directory and doing ls -lia . You will see . and .. entries. I had you use the '-i' flag on ls to get inode numbers: note them for . and ... Go up a directory, but doing cd .. or cd /something/soemthingelse/whatever. Do ls -lia again. Notice that the inode number of . is identical to that of .. in your first listing. Every directory has directories in it when created, named "." and "..". The "." entry has the same inode number as the directory's name does in its parent directory. The ".." entry is always the parent directory. If you do ls -li / you will see that "." and ".." have the same value.

This convention eliminates the need for special case code to reference the current directory: it's always named ".". It eliminates the need for special case code to "go up one directory": it's always "..". The only special cases are the root directory, and network-mounted filesystems. The filesystem root has "." and ".." with the same inode number, not different. Network-mounted filesystems have a discontinuity in inode numbers at the mount point, and behavior depends on what the remote filesystem is, and what protocol is used to mount it.

As far as the change in prompt, when you invoked mv ../ttt ../tttt, you actually renamed your shell's working directory. You didn't invoke a shell command that checks working directory until you did cd ., so the intervening pwd reports the old name, /tmp/tt.

Related Question