It’s about inode

In the Linux systems, more than often there is a modern File Management System (Linux File System) to manage files and directories for users. Each file or directory has an inode number that uniquely identifies it. The inode also contains info about the owner, the rights, the file size and modification time of the file it points to.

When use stores files on the disk, it can be considered as “delegate” the file to the file system. Whether it is stored on regular hard drive, SSD or optical disk is totally up to the file system. With inode number at hand, a user can easily ask for the specific file from the file system without worrying about the underlying details.

Use ls -i command can list the inode number of files (first column).

$ ls -i 
 239114 Applications
 239245 Downloads    
 239121 Desktop
 239229 Documents 

Difference of symbolic and hard link

There are similarities creating symbolic or hard links in Linux system. But fundamentally these are two species of animals.

Symbolic link is basically a “shortcut” to the original file. It is a text file with special content: path to the original file. It has is own inode number since it is a standalone regular file. Deleting the “shortcut” won’t hurt the original file in any way. The path contained in the “shortcut” can be valid or not valid. When it is invalid, it is called a “broken link”.

Let’s create a regular file my-file.txt and add a little content to it:

$ touch my-file.txt
$ echo abcdefg > my-file.txt # Add some text
$ ls -i
6985592 my-file.txt

Use ln -s to create a symbolic link to it:

$ ln -s my-file.txt my-symbolic-link.txt
$ ls -i
6985592 my-file.txt
6986078 my-symbolic-link.txt

Notice two files have distinct inode numbers (6985592 & 6986078). They are different files.

Hard link, on the other hand, is the cheating behavior of files system. A hard link points to exactly the SAME file or say the data of the SAME file. Different from symbolic link, hard links doesn’t have any content about “path” to the original file, it IS the original file, just a different name.

When you have my-file.txt and creates a hard link my-hard-link.txt, hey, now they share the same inode number!

Use ln to create a hard link:

$ ln my-file.txt my-hard-link.txt
$ ls -i
6985592 my-file.txt
6985592 my-hard-link.txt
6986078 my-symbolic-link.txt

Here my-file.txt and my-symbolic-link.txt share the same inode number 6985592. From file system’s view, they are the same.

There are two cautions regarding hard links:

  • Symbolic links can span across files systems, while hard links is constrained on the same file system.
  • Each hard link contains a counter. It marks how many times a file is hard-linked. When the counter drops to 0, nobody is using that data, it can be deleted.

Use ls -l to better view links

Use ls -i can view the inode number of files. Even better, use ls -l can clearly tell link types and counter.

$ ls -l
-rw-r--r--  2 jack  staff   8 Aug 14 14:40 my-file.txt
-rw-r--r--  2 jack  staff   8 Aug 14 14:40 my-hard-link.txt
lrwxr-xr-x  1 jack  staff  11 Aug 14 14:43 my-symbolic-link.txt -> my-file.txt

The second column, 2 2 1 represents the counters. my-file.txt is hard linked to my-hard-link.txt, so the counter is 2. my-symbolic-link.txt is a standalone file, so the counter is 1.

The third line, my-symbolic-link.txt is pointing to my-file.txt, denoted by an arrow.

If we add more content to the original file to make it larger:

$ echo 123456 >> my-file.txt
$ ls -l
-rw-r--r--  2 jack  staff  15 Aug 14 15:02 my-file.txt
-rw-r--r--  2 jack  staff  15 Aug 14 15:02 my-hard-link.txt
lrwxr-xr-x  1 jack  staff  11 Aug 14 14:43 my-symbolic-link.txt -> my-file.txt

The fourth column, change from 8 8 11 to 15 15 11. The number represents the file size in bytes. We can see hard link also changed its files size while symbolic link is immune to the change.

If we delete the hard link, the counter will drop by one:

$ rm my-hard-link.txt
$ ls -l
-rw-r--r--  1 jack  staff  15 Aug 14 15:02 my-file.txt
lrwxr-xr-x  1 jack  staff  11 Aug 14 14:43 my-symbolic-link.txt -> my-file.txt

Notice the seconde column, changed from 2 2 1 to 1 1.

Did I just edited the real file?

When you using vim to edit a file, or the link to the file, you wonder if you are actually editing the original file.

For hard links, yes you are definitely editing the original file since the inode is unique.

For symbolic links, vim would follow the link and edit the original file.

You may need to use ln -sf command to modify the symbolic link itself.

How to find hard links using commands

It is cool to know the counter of hard links using ls -l but if the file is hard-linked dozens of times and scattered across many places in the file system, then it won’t be easy to find them all.

There are two practical ways to find them all:

  • First command
find ~/ -samefile my-file.txt

This command searches in the directory of ~/ and finds all hards links to the file my-file.txt.

  • Second command(s)
$ ls -i my-file.txt
$ find ~/ -inum <inode_number>

This set of command first reads the inode number of my-file.txt, it searches directory ~/ to find the other hard links that have the same inode number.