I'd strongly suggest not to use find -L
for the task (see below for explanation). Here are some other ways to do this:
If you want to use a "pure find
" method, and assuming the GNU implementation of find
, it should rather look like this:
find . -xtype l
(xtype
is a test performed on a dereferenced link)
portably (though less efficiently), you can also exec test -e
from within the find
command:
find . -type l ! -exec test -e {} \; -print
Even some grep
trick could be better (i.e., safer) than find -L
, but not exactly such as presented in the question (which greps in entire output lines, including filenames):
find . -type l -exec sh -c 'file -b "$1" | grep -q "^broken"' sh {} \; -print
The find -L
trick quoted by solo from commandlinefu looks nice and hacky, but it has one very dangerous pitfall: All the symlinks are followed. Consider directory with the contents presented below:
$ ls -l
total 0
lrwxrwxrwx 1 michal users 6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/
If you run find -L . -type l
in that directory, all /usr/share/
would be searched as well (and that can take really long)1. For a find
command that is "immune to outgoing links", don't use -L
.
1 This may look like a minor inconvenience (the command will "just" take long to traverse all /usr/share
) – but can have more severe consequences. For instance, consider chroot environments: They can exist in some subdirectory of the main filesystem and contain symlinks to absolute locations. Those links could seem to be broken for the "outside" system, because they only point to proper places once you've entered the chroot. I also recall that some bootloader used symlinks under /boot
that only made sense in an initial boot phase, when the boot partition was mounted as /
.
So if you use a find -L
command to find and then delete broken symlinks from some harmless-looking directory, you might even break your system...