Reputation: 2927
I run find
and iterate through the results with [ \( -L $F \) ]
to collect certain symbolic links.
I am wondering if there is an easy way to determine if the link is broken (points to a non-existent file) in this scenario.
Here is my code:
FILES=`find /target/ | grep -v '\.disabled$' | sort`
for F in $FILES; do
if [ -L $F ]; then
DO THINGS
fi
done
Upvotes: 66
Views: 48795
Reputation: 293
On recent versions of bash
(5.1.16) test -e "$link"
or [[ -e "$link" ]]
do not behave as expected, failing to recognize the link as broken.
I suggest using readlink(1)
as well as testing for the existence of the link as follows:
if [[ ! -L "$link" ]]; then
echo "Missing or not a symlink"
else
readlink -q "$link"
if [[ $? -ne 0 ]]; then
echo "Broken"
fi
fi
Upvotes: 1
Reputation: 10416
If it does qualify as a symbolic link, but is „not existing“, its a broken link.
if [[ -h $link && ! -e $link ]] ; then
_info "$link is a BROKEN SYMLINK"
fi
Upvotes: -1
Reputation: 728
# test if symlink is broken (by seeing if it links to an existing file)
if [ ! -e "$F" ] ; then
# code if the symlink is broken
fi
Upvotes: 64
Reputation: 212664
If you don't mind traversing non-broken dir symlinks, to find all orphaned links:
$ find -L /target -type l | while read -r file; do echo $file is orphaned; done
To find all files that are not orphaned links:
$ find -L /target ! -type l
Upvotes: 2
Reputation: 6290
This finds all files of type "link", which also resolves to a type "link". ie. a broken symlink
find /target -type l -xtype l
Upvotes: 5
Reputation: 3985
this will work if the symlink was pointing to a file or a directory, but now is broken
if [[ -L "$strFile" ]] && [[ ! -a "$strFile" ]];then
echo "'$strFile' is a broken symlink";
fi
Upvotes: 12
Reputation: 86974
This should print out links that are broken:
find /target/dir -type l ! -exec test -e {} \; -print
You can also chain in operations to find
command, e.g. deleting the broken link:
find /target/dir -type l ! -exec test -e {} \; -exec rm {} \;
Upvotes: 39