Take the 2-minute tour ×
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.

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.

share|improve this question
1  
have a look at this question: stackoverflow.com/questions/100170 –  Stefan Nov 2 '10 at 16:39
add comment

2 Answers 2

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. With some shells, you may need to replace pwd by exec pwd for proper symbolic link following.

find /haystack -type l -exec sh -c 'cd -- "$0" && pwd' {} \; | \
grep -Fx "$(cd /target && pwd)"

And here's my obligatory zsh solution.

echo /haystack/**/*(@e\''[[ $REPLY -ef /target ]]'\')
share|improve this answer
    
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 3 '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 Nov 3 '10 at 19:53
add comment

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.

share|improve this answer
    
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 2 '10 at 16:45
add comment

Your Answer

 
discard

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.