Exploring Linux Hard and Symbolic Links

A link is a way to give a file multiple identities. Links in Linux are similar to shortcuts in Windows, and aliases in Mac OS. However, on a Linux filesystem, a file does not get deleted until there are no remaining hard links to it.

Hard Links vs Symbolic Links

Each Linux filesystem uses a single inode number to represent a file, and each inode number is unique inside its filesystem (at least in theory). Hard links are based upon inode numbers – two hard-linked files have the same inode number or, inode id. Due to this reason, the hard-linking across file systems is not allowed as this would lead OS into confusion. Imagine a situation where two filesystems already contain their own version of data.txt file with the inode number of 44733, and somebody tries to create a hard link from one filesystem to another. BOOM? Exactly.

Since there is no way to tell the difference between a hard link and its original name, most filesystems also don’t allow hard links to directories. This would eventually cause directory loops and dangling directory subtrees. Therefore we have two main hard link limitations:

  1. Hard links cannot link directories.
  2. Hard links cannot cross file system boundaries.

On the other hand, a symbolic (soft link, or symlink) link is a special file containing a path to another file. This path can be absolute, or can be relative. Symbolic links allow to associate multiple filenames with a single file as well as to create links between directories.

Since symlink stores no info beside the path of the file it points to, it can be used across filesystems. However, symbolic link behaves differently when the source of the link is moved or removed. If the source file is deleted, symlink gets broken as it points to a non-existing file. The following are the main features of symbolic links:

  1. Symbolic links can create links between directories.
  2. Symbolic links can cross file system boundaries.
  3. Symbolic links are not updated if the source gets removed.

Note, that hard links always refer to the source, even if moved or removed.

Managing Links

Linux provides the ln command to create links.

$ ln [options] source link

The source is the original file, and the link is the name of the link we want to create. By default, if no options are specified,  ln command creates a hard link.

# touch file
# ln file hardfile
# ls -li
272956 -rw-r----- 2 root root 0 Nov 22 20:55 file
272956 -rw-r----- 2 root root 0 Nov 22 20:55 hardfile

Note that hard links always have the same inode number. When we create a hard link, the inode reference counter increases to 2, or in other words, we have two links to the same file. As long as the counter is not equal to zero, the filesystem does not remove the inode. Even if we remove the source file, the filesystem only deletes one of the two existing links. Another links still exists. As long we do not delete the last hard link the file is available.

To create a symbolic link, we have to pass the -s option to the command:

# ln -s file softfile
# ls -l
lrwxrwxrwx 1 root root   4 Nov 22 21:04 softfile -> file

If in use with the -f option, ln removes any existing links or files that have the target link name. The -i option has a very similar effect, but it prompts before replacing any existing files and links.

As mentioned earlier, we ordinarily cannot create hard links to directories. However, the root user can attempt to do so, though, by passing the -d or -F option to ln. In a real world, this feature is likely to fail because most filesystems simply don’t support it:

# mkdir /tmp/testdir
# ln -d /tmp/testdir/ /mnt/newdir
ln: failed to create hard link `/mnt/newdir' => `/tmp/testdir/': Operation not permitted