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
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”!