How to effectively trace hardlink in Linux?

First, there is no original file in the case of hard links; all hard links are equal.

However, hard links aren’t involved here, as indicated by the link count of 1 in ls -l’s output:

$ ll -i /usr/bin/bash /bin/bash  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /usr/bin/bash*

Your problem arises because of a symlink, the bin symlink which points to usr/bin. To find all the paths in which bash is available, you need to tell find to follow symlinks, using the -L option:

$ find -L / -xdev -samefile /usr/bin/bash 2>/dev/null
/usr/bin/rbash
/usr/bin/bash
/bin/rbash
/bin/bash

I’m using -xdev here because I know your system is installed on a single file system; this avoids descending into /dev, /proc, /run, /sys etc.


how do I trace the original file or every hardlink using /usr/bin/bash file as reference

With GNU find (or any other version of find that has the -samefile option), and assuming that /usr/bin/bash is located on the / filesystem, this is correct:

find / -xdev -samefile /bin/bash

Use -xdev since hard links can't cross filesystem boundaries. Do not redirect errors: if you don't have permission to traverse a directory, a hard link could be present under that directory and you'd miss it.

The mistake you're making is that you're looking for another hard link that doesn't exist. You actually have the information to know that it doesn't exist:

1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*
                   ^

The hard link count of /bin/bash is 1.

There is a single file in / which is the same as /usr/bin/bash. The file /bin/bash is the same as /usr/bin/bash for a different reason: the directories /bin and /usr/bin are the same file. Since find / -samefile /bin/bash points to /usr/bin/bash, /bin has a symbolic link to /usr/bin. More precisely, from the information in the question, and assuming that /bin is not a directory hard link (a poorly supported, rarely used feature), we know that /bin is a symbolic link which resolves to /usr/bin; it could be a symbolic link to another symbolic link and so on eventually resolving to /usr/bin or to some equivalent path such as ///////usr/bin/, but most likely it's a symbolic link whose target is /usr/bin.

Looking for all symbolic links to a file on the whole system is not particularly productive. For example, on Linux, there's a file /proc/*/exe which is a symbolic link to /usr/bin/bash (or /bin/bash) for every process that's running bash. And if you look for symbolic links to a directory, you'll end up inside infinite recursion, for example with /proc/*/root pointing to / (except for chrooted processes).

If you need to know whether two paths point to the same file, on Linux, you can use either of

[ /bin/bash -ef /usr/bin/bash ]
test /bin/bash -ef /usr/bin/bash

(-ef isn't POSIX but it's in dash, bash, BusyBox and GNU coreutils). If you need to get a canonical path to a file, in the sense that distinct files always have distinct canonical names, you can use

readlink -f /bin/bash

(This can miss files that are equal via mounted directories, for example if the same network location is mounted in two different ways.)