I want to do some housekeeping in a directory, and I want to see if a given directory has any symlinks pointing to it. I can easily enough see what directory a symlink points to, but now I want to see the relationship in reverse.
2 Answers
Symbolic links are not tracked, so you'll have to perform an exhaustive search. Furthermore, symbolic links are textual, so they keep “existing” even if the filesystem they reside on is unmounted (and they may have a different target if mounted in a different place or if you rename directories). So the most you can do is find the symbolic links pointing to a particular file (or directory), say /target
, in a particular directory hierarchy, say /haystack
.
(Note that I assume you are really looking for symbolic links to a particular directory. Finding symbolic links pointing into a directory (i.e. to a file or subdirectory of that directory) or accross a directory (i.e. that may become dangling if you remove the directory) are much harder problems.)
With some versions of find (e.g. on (recent enough) Linux, FreeBSD or Mac OS X), you can easily look for symbolic links whose target is /target
:
find -L /haystack -xtype l -samefile /target
On systems whose find
command doesn't have the -samefile
primary, you can use ksh or bash instead, if available. Remove -xtype
if it's also not supported; then the command will also list the target itself (or any hard link to it).
find -L /haystack -xtype l -exec ksh -c '
for x; do [[ $0 -ef $x ]] && printf "%s\n" "$x"; done
' /target {} +
Doing this with only POSIX tools is a lot harder, due to the lack of POSIX ways to test same-file-ness or obtain information about symbolic links. Here's a solution for directories; it assumes there are no newlines in any filename.
find /haystack -type l -exec sh -c 'cd -P -- "$0" && pwd' {} \; |
grep -Fx "$(cd -P /target && pwd)"
And here's my obligatory zsh solution.
echo /haystack/**/*(@e\''[[ $REPLY -ef /target ]]'\')

- 544,893

- 829,060
-
Okay, this is actually what I need in my case. In a single directory with no recursion, I want to see if any symlinks to it also reside in that directory, so I know whether deleting it will cause any breakage. Will
find -L ./ -xtype l -samefile /target
do the trick? If I wrapped it in a foreach() covering each file, I could search all the files for symlinks to them, right? – user394 Nov 03 '10 at 19:41 -
@user394: I don't understand the requirement in your comment, there are several ambiguous “it”s and “the”s. Could you reformulate it more clearly, perhaps with examples? – Gilles 'SO- stop being evil' Nov 03 '10 at 19:53
-
For
find -L /haystack -xtype l -exec ksh...
, ITYMfind /haystack -type l -exec ksh...
unless you do intend to descend into symlinks to directories (in which case you'd have used***
inzsh
). – Stéphane Chazelas Jun 15 '16 at 08:35 -
Note that
-ef
has been requested be added to POSIX as it's widely supported. – Stéphane Chazelas Jun 15 '16 at 08:42
You'll need to search from /
using find(1) and the -type l
option to identify all links, followed by a grep(1) to isolate the links of interest.

- 557
-
grep
alone might be not enough, if relative links are involved like../other
. You might need to expand detected links and compare with the full path to your dir of interest for a match. – alex Nov 02 '10 at 16:45