Page Body

How to Find All of a File's Hard Links

Hard links are a great way to have multiple names associated with a file on a file system. However, over time, you may decide that an audit is warranted and need a way to identify all of the hard links that you have created for a file.

Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.

The find command's -samefile ex_file_path test provides an efficient solution. After providing this test a file path, the find command will display the paths of all files in the search directory tree you specify that are hard links of each other:

find ex_directory_tree_to_search -samefile ex_file_path

To make things easier, we can a create a function that can do extra processing to clean up the command's output:

# Display file hard links
f_dsp_hlinks() {
    ab_path_regex='^\/.*[^'\''"]*$'  # Set absolute path regular expression

    if [[ "${#}" -ne 2 ]]; then
        err_msg='\nThis function requires two arguments:\n\n1. A directory '
        err_msg+='tree to search\n2. A file to find hard links for'
        echo -e "${err_msg}" 1>&2

        return 1
    elif [[ "${1}" =~ ${ab_path_regex} ]]; then
        find "${1}" \
            -type d \( -path '/proc' -o -path '/run' \) -prune -o \
            -samefile "${2}" -print 2>&1 | grep -v "Permission denied|${2}"
    else
        err_msg='\nSpecify search directory tree as an absolute path.'
        echo -e "${err_msg}" 1>&2

        return 1
    fi
}

The function takes two arguments:

  1. The absolute directory path to search
  2. The file path to find all hard links for

For example, the following command searches the current user's home directory for quotes.md's hard links:

f_dsp_hlinks "${HOME}" '/home/amnesia/Documents/quotes.md'

The f_dsp_hlinks() function can be broken down like so:

  • ab_path_regex='^\/.*[^'\''"]*$' specifies a regular expression for matching absolute pathnames.
  • if [[ "${1}" =~ ${ab_path_regex} ]] ensures that the provided search directory tree is an absolute pathname, which is required for the find test that we are going to use to exclude certain directories from our search.

    If an absolute pathname is not provided, the function's else block executes and sends a reminder message to the standard error.

  • -type d \( -path '/proc/' -o -path '/run/' \) -prune is a test that checks to see if a file system object is a directory that matches one of the pseudo file systems, /proc/ or /run/. If the test returns true, the directory is not descended into.

    Otherwise, -samefile "${2}" -print ensures that the find command prints the desired output and 2>&1 directs any find errors from the standard error to the standard output.

    The piped output is sent to grep -v "Permission denied|${2}", which filters out any lines regarding Permission denied errors and the original hard link file we originally provided to the function.

Enjoyed this post?

Subscribe to the feed for the latest updates.