Link to home
Start Free TrialLog in
Avatar of wesly_chen
wesly_chenFlag for United States of America

asked on

Search for the dead symbolic link

I would like to search the "DEAD" symbolic link on my Unix/Linux system.
I do
# find / -type l -print
to search the symbolic link.
Then how to I do to determine the link is dead.

I saw the red color in the output of "ls" if the link is dead. But how can I use the command or script to determine the dead link.
I found
find / - type l -print | perl -nle ' -e || print '
from the internet but it doesn't work for me.
Avatar of blkline
blkline

How about something like this?  (This is a quick knock-off so not very efficient)

for ln in $(find . -type l -ls | sed -e 's/^.*>//'); do echo $ln; if [ -d $ln -o -f $ln ]; then echo "Good"; else echo "Dead"; fi; done
Duh... now that I look at this I realize that you'll only find out if the reference is good and the referenced file.  Let's try again:

find . -type l -ls | \
while read ln
do
   referenced=$(echo $ln | sed -e 's/^.*>//')
    if [ -d $referenced -o -f $referenced ]; then
           echo "$ln is good."
    else
           echo "$ln is dead, Jim."
    fi
done
ASKER CERTIFIED SOLUTION
Avatar of blkline
blkline

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of yuzh
The easy way to do it use find with "-follow"

eg:
find /dir -type l -follow
      will return
                "/dir/xxx No such file or directory"
                or
                "find: cannot follow symbolic link [whatever]:
      No such file or directory" for each broken link."

                The output depands on your version of OS.
You can also use the following script:

#!/bin/ksh
     for link in `find . -type l `
       do
        cat $link > /dev/null 2> /dev/null;
        if [ $? -ne 0 ] ;  then
           echo $link
        fi
       done
exit
Avatar of wesly_chen

ASKER

I got the following answer for perl expert:
perl -MFile::Find -wle'find sub { -l && do { unless ( stat ) { print "$File::Find::name: dead" }}}, "/";'

However, it requires File::Find module of Perl. Any other simple one line solution?
Here's a oneline solution:

find /dir -type l | xargs cat > /dev/null

Should throw an error for the ones that are broken on the screen.
> find /dir -type l | xargs cat > /dev/null
Sound good.
But how can "rm" the dead soft link automatically? (Of cause, "rm -i" to comfirm removal)
Or (test on Solaris only!)

(find /dir -type l | xargs cat > /dev/null)2>&1  | awk '{print $4}'

will print all the broken link file names only
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial