Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In Linux, what is the best way to find all symbolic links that point to a given file (regardless of whether the symlink is relative or absolute)? I realize this will require scanning the whole filesystem.

share|improve this question
up vote 6 down vote accepted

GNU find has the -samefile test. According to the man page:

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

This will find all links to /path/to/file, which includes hard links and the file itself. If you only want symlinks, you can individually test the results of find (test -L).

You should read up on what the effects of -L are and ensure that it won't cause you any problems with your search.

Note: While the documentation says it looks for files with the same inode number, it does appear to work across filesystems.

e.g. /home and /tmp are separate filesystems

$ touch ~/testfile
$ ln -s ~/testfile /tmp/foo
$ ln -s /tmp/foo /tmp/bar
$ mkdir /tmp/x
$ ln -s ~/testfile /tmp/x/baz
$ find -L /tmp -samefile ~/testfile

Note how this is returning /tmp/bar, which is a symlink to /tmp/foo, which is a symlink to ~/testfile. If you only wanted to find direct symlinks to your target file, this wont work.

share|improve this answer

Perhaps the shortest way would be:

target="/usr/bin/firefox"    # change me
dir="/usr/bin"               # change me
realtarget="$(realpath "$target")"
for file in $(find "$dir" -print); do
    realfile="$(realpath "$file")"
    test "$realfile" = "$realtarget" && echo "$file"

But it's not very efficient.

If you don't have realpath, install it, e.g. apt-get install realpath. You could also use stat -N or ls -l or pwd -P to emulate realpath, but those ways are harder.

Also, the above example won't handle file names with spaces in it properly. Here's a better way to do it. Note that IFS=$'\n' requires bash or zsh.

target="/usr/bin/firefox"    # change me
dir="/usr/bin"               # change me
realtarget="$(realpath "$target")"
find "$dir" -print | while read -r file; do
    realfile="$(realpath "$file")"
    test "$realfile" = "$realtarget" && echo "$file"
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.