As tidy sysadmins, we like to ensure that the little things are just as well covered as the big things (when time permits). One of these things is ensuring that our systems aren't full of broken symlinks.

Why are these little blighters a problem? Because they make you think files are there when they're not, they can be an indication of something more annoying, and because the (smallish) OCD part of me goes batshit crazy with all those warnings when running certain commands (like grep -r).

So, how would one go about detecting (and reporting, via e-mail or monitoring system) broken links across the parts of a system that the admin is responsible for (no point telling me that ~jbloggs has a bunch of broken symlinks, that's his problem)?


The problem with -L is that is has the side effect of expanding the search into sub-directories that are the targets of symlinks, which might not be expected or desired.

With GNU findutils version of find:

<!-- language: bash -->
find /path/to/search -xtype l

except that doesn't find cyclic symbolic links.

-execdir in the other answer isn't as portable, so distilling it down to a portable solution that finds broken symbolic links, including cyclic links:

<!-- language: bash -->
find /path/to/search -type l -exec test ! -e {} \; -print

See this question, or ynform.org for further discussion. Also see the findutils documentation for details. The ynform.org link also presents a method for detecting only cyclic links.


Many ways to skin a cat

This is quite portable (-L is posix requirement)

find -L /path/you/care/about -type l 2>/dev/null | mail -s "Broken symlinks detected" womble@example.com

You didn't define broken, the above would send you broken links that have no target in the part of the filesystem you care about. It also reports on stderr filesystem loops and Too many levels of symbolic link etc. problems. If you care about them too then redirect stderr to your mail

find -L /path/you/care/about -type l 2>&1 | mail ...

If your find supports it -readable is useful and fast

find /path/you/care/about -type l ! -readable | mail ...

The above includes links with Too many levels of symbolic link problems in it's output but not filesystem loops.

If the parts of the filesystem you care about have different paths then

find /path/you/care/about /another/path ...

I will give you a Linux answer and you could adjust it to your Unix, if needed:

find . -type l ! -execdir test -e {} \; -print >> broken_symlinks.txt; mutt -s "Broken symlinks" womble@example.com < broken_symlinks.txt; rm -f broken_symlinks.txt

Second option is ls -LR | grep 'cannot access' or some modifications from the find command above.


Yeah, this is even better: find . -type l ! -execdir test -e {} \; -print | mail -s "Broken symlinks" womble@example.com

  • 1
    Why not get rid of broken_symlinks.txt entirely and just use a pipe? And use mail instead of mutt to send the e-mail? – womble Jul 31 '11 at 2:41

This is a nice way of doing it with GNU find:

find <root_dir_of_find> -follow -lname '*' | mail sysadmin -s 'Broken symlink report'

The reason this works is because -lname with -follow (or -L) "...this test returns false unless the symbolic link is broken", according to the find man page.

It would probably be wise to run this sort of disk scanning when the server is not heavily used. It may be useful to use nice and/or ionice (see this blog for a nice description of ionice) to reduce the load on the server while running this task.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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