1. Overview

In this article, we’ll learn the meaning of the mysterious double (..) and single (.) dots in Linux.

2. Linux Inodes

In Linux, inodes are the data structures used for storing all the information about a file except for its name and contents. In a directory, all files exist as entries with the filename and the corresponding inode number used to fetch information. An Inode holds the following information:

  • Creation/Modification Time
  • Size
  • Permissions
  • Owner

Inode numbers are unique integers within the filesystem and refer to a single file only. Inodes are usually stored at the beginning of partitions. Running out of inodes can cause “no space left” errors even if space is free. We can use inode numbers to find all links to a file too.

We can use the ls command with the -i flag to list inode numbers along with filenames:

$ cd /usr/bin
$ ls -i
  71520 [
  71521 [[
  48516 aconnect
  71522 acpid
  71523 add-shell
 129429 addgnupghome
  71524 addgroup
 127833 addpart
  30369 addr2line
...

The separation of a file’s name from its metadata allows the implementation of hard links. A hard link is just a pointer to the inode of a given file, so it points to the same location on the filesystem. It is not a copy of a file, so modifications to a hard link would modify the original file as well.

We can create hard links with the ln command:

$ echo hello > original
$ cat original
hello
$ ln original hardlink
$ echo "This will modify the original" >> hardlink 
$ cat original
hello
This will modify the original
$ ls -i original hardlink 
     89 hardlink       89 original

As we can see, they both have the same corresponding Inode. We should note that even if we delete the original file, the hard link will remain accessible. This is the major point that distinguishes hard links from symlinks.

4. What Do ‘.’ and ‘..’ Mean?

‘.’ and ‘..’ are similar to the hard links that we discussed above as they increase the link count of an Inode, but we also cannot remove them since they’re built into the filesystem. Moreover, hard links to directories are not possible. Hence we cannot exactly refer to them as hard links, and the more accurate term is “name-inode maps”.

In filesystems, we use the double dot (..) to access the parent directory, whereas the single dot (.) represents the current directory.

Let’s try to use realpath to confirm this:

$ pwd
/tmp/somedir
$ realpath .
/tmp/somedir
$ realpath ..
/tmp

Here /tmp/somedir is the current directory and /tmp is its parent.

We can prefix a filename with a single dot (.) to “hide” it, so it will only show up if we pass the -a flag to ls:

$ echo "Hello" > normal_file
$ echo "Secret" > .hidden_file
$ ls
normal_file
$ ls -a
.             ..            .hidden_file  normal_file

5. Using ‘.’ and ‘..’ in Bash

It might come as a surprise, but the double and single dots have their application in bash too. However, this is unlike their regular usage in filesystems.

In Bash, the double dot (..) is used to generate a sequence such as numbers or characters:

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z

We specify the starting point before the double dot and the ending point after it.

We use the single dot (.) to source a file, which basically means to execute it in the current shell:

$ echo "export VARIABLE='This variable will be set in the shell!'" > source_me
$ . ./source_me
$ echo "$VARIABLE"
This variable will be set in the shell!

6. Conclusion

In this article, we learned about Linux Inodes, hard links, and the applications of double dot and single dot.