counting and listing hard links on Linux

A hard link is actually nothing more than a regular directory entry, which in turn can be seen as a pointer to the actual file’s data on the disk. The cool thing about hard-links is that a file can be stored once on the disk, and be linked to multiple times, from different locations/entries, without requiring to allocate extra disk space for each file instance.

But then a question arises: Given a specific file on disk, how can someone know whether it is linked to by other directory entries or not? This can be easily answered using the ls command:

giannis@zandloper:/etc$ ls -l passwd
-rw-r--r-- 1 root root 1402 2008-03-30 17:49 passwd

Do you ever wonder what is this small number between the file permissions and the owner in the output of ls’s long listing format (its value is usually “1” for files, or “2” for directories)? This number is actually the link-count of the file, when referring to a file, or the number of contained directory entries, when referring to a directory (including the . and .. entries).

So, the answer to the question “are there any other directory entries linking to this file, and if so, how many?” can be simply answered by executing ls -l for this file and checking the link-count column. If it is just 1 that means that this is the one and only instance. If it’s greater than 1 then there are other directory entries linked to that same file.

Now, imagine you find out that a file is linked to by some other directory entry. The next thing you would want to know is who is linking to that file. To figure this out you must know what all these directory entries share in common. And that is, an inode.

An inode is a data structure used internally by a (unix-like) file system to store information about a file (it can be also considered as the file’s meta-data). Every inode has a unique (in the scope of the file system) identity number. We will use this property to locate all the hard links of a file within a file system. And this is how we can do it.

By passing the -i option to the ls command we also get the inode number for a directory entry:

giannis@zandloper:/etc$ ls -i passwd
199053 passwd

In this case, the inode number for the /etc/passwd file is 199053. Now that we have the inode number we can now do the actual search for directory entries that have that same inode number. But because it would be pointless to do such a thing since we know that there are no other hard links of this file in existence (recall the link-count “1” in the output of the previous ls -l command which states that there is only one instance of that file), I’m going to first create a hard link of the file in my home directory:

giannis@zandloper:~$ ln /etc/passwd
giannis@zandloper:~$ ls -l passwd
-rw-r--r-- 2 root root 1402 2008-03-30 17:49 passwd

Now we’re going to search the entire file system for files with inode number equal to 199053. To do so we are going to use the find command and its -inum option:

giannis@zandloper:~$ sudo find / -inum 199053

And that was it! I hope you learned something useful today :-).

UPDATE: As “KokNikol” pointed out in the comments section, it seems that there is an easier way to locate all the hard links of a file. This is accomplished by using the “-samefile” parameter of the find command:

giannis@zandloper:~$ sudo find / -samefile passwd

The benefit of using “-samefile” is that this way you omit the intermediate step of finding the file’s inode number. Thanks “KokNikol”!

This entry was posted in Uncategorized. Bookmark the permalink.

14 Responses to counting and listing hard links on Linux

  1. kamarul says:

    good explaination and example.
    Always overlook by linux users.

    Great job!!

  2. the blue mountain says:

    thank you for this explanation. that’s exactly what i was looking for !

  3. jim s says:

    i am using php
    i have a number of files with file1 plain text document
    file 2 link to plain text document
    i need to remove the link and have file 1 and file 2 seperately hold the same information.
    how do i break the link and have file 1 and file 2 with the same information?
    i have tried to use SplFileInfo and other functions but they do not seem to work. as you can tell, i am inexperienced in this area of programming.

    any help would be appreciated!


    jim s.

  4. Viji says:

    thanks for making it so simple to understand !

  5. Stephan says:

    This is one very useful tutorial. Thanks a lot and yes, I learned something useful today.

  6. gto says:

    Wow, this post is really zen.
    And it helped me find my second link (it was in the trash:)


  7. Genuine post.. Really helpful for Linux users..

  8. KokNikol says:

    This helped me a lot. Sometimes the man page can be very long and one can miss something like the -inum option.
    + you explained how everything is organized!

    Thank you!

  9. KokNikol says:

    I found an easier way, in case you just want to find and list all the files with the same inode use the -samefile option:

    from the man page

    -samefile name
    File refers to the same inode as name. When -L is in effect, this can include symbolic links.

    the command from your example in this case would be:

    $sudo find / -samefile passwd

  10. Vijay says:

    Superbly explained…

  11. Desley says:

    good explained

  12. Charles says:

    Thanks; well explained

Leave a Reply

Your email address will not be published. Required fields are marked *