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, it should rather look like this:find . -xtype l
(
xtype
is a test performed on a dereferenced link) This may not be available in all versions offind
, though. But there are other options as well:You can also exec
test -e
from within thefind
command:find . -type l ! -exec test -e {} \; -print
Even some
grep
trick could be better (i.e., safer) thanfind -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...