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 ofsymlinks
, which might not be expected or desired.With
GNU findutils
version offind
: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: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)
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
If your find supports it
-readable
is useful and fastThe 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
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" [email protected] < broken_symlinks.txt; rm -f broken_symlinks.txt
Second option is
ls -LR | grep 'cannot access'
or some modifications from the find command above.Edit:
Yeah, this is even better:
find . -type l ! -execdir test -e {} \; -print | mail -s "Broken symlinks" [email protected]
This is a nice way of doing it with GNU find:
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/orionice
(see this blog for a nice description of ionice) to reduce the load on the server while running this task.Fedora and Ubuntu provide the
symlinks
utility. The utility is a native elf executable, and not a wrapper shell script. The utility was preinstalled on Fedora. You may need to install the utility on Ubuntu.With the
symlinks
utility you can audit for dangling links with the following command.If the targets of the dangling links are OK to delete, then issue the following to delete them.
Here is an example of the output on a Fedora 31 server. The
debian-logo.png
andubuntu-logo.png
are correct.