Symbolic links are special files that contain a reference to another file or directory. They are called broken when they point to a target that doesn’t exist.
File, Link, and Broken Links
You can try this command to create a file, a valid link, and two broken links:
$ touch a
$ ln -s a b
$ ln -s c d
$ ln -s e e
Then you can print files information:
$ file *
a: empty
b: symbolic link to `a'
d: broken symbolic link to `c'
e: broken symbolic link to `e'
Because file c doesn’t exist, d is said to be broken. e is also considered to be broken because it points to itself, which makes the link unresolvable.
Recursive Search
The command find can be used to search the filesystem for broken links:
$ find . -type l -exec test ! -e {} \; -print
./d
./e
This command simply translates the definition of a broken link: “a file whose type is link but which doesn’t exist”. Because find doesn’t try to follow symbolic links, no error message is printed for loop links (e.g. e).
Of course the -print option can be replaced by whatever you want to do with these broken links (i.e. -delete, -exec file {} \;).
Adaptive Behavior
If you need a different behavior whether the link is a loop or simply points to a non-existing file, then you can use the %Y escape sequence of -printf which indicates the file’s type with a letter: L=loop, N=nonexistent.
$ find . -type l -exec test ! -e {} \; -printf '%Y %p\n' \
| while read type link; do
case "$type" in
N) echo "do something with broken link $link" ;;
L) echo "do something with cyclic link $link" ;;
esac
done
do something with broken link ./d
do something with cyclic link ./e