QUESTION: ========= I have a number of broken symbolic links on the file systems of computers which I manage. I know I can find all of the symbolic links in a given filesystem using the following : (1) ls -l | grep '^l' (2) find /dir -type l -exec ls -l {} \; Is there a way, I wonder, to 'follow' a link to test to see if it is valid? 'ls -L' isn't reporting any errors for my broken links. I would like to throw together a Bourne script to automate the process of finding and deleting dangling links. P.S. I wish I did, but I don't know Perl. If we could please limit this discussion to Unix shell scripting, I would appreciate it! ANSWERS: ======== (1) find /dir -type l -follow will return "find: cannot follow symbolic link [whatever]: No such file or directory" for each broken link. - Alex Shephard (2) See Figure 5 at the following PDF for a csh script http://swexpert.com/C4/SE.C4.DEC.96.pdf (but really, I'd rather use perl for this job...) :-) - Darren Dunham (3) 'test -r' fails on a hanging symlink. The /bin/sh-ism would be something like: if [ -h $fname ] && [ ! -r $fname ] ; then echo "Bad symbolic link!" fi - Jay Lessert (4) Here is a shell script to find broken links: ----cut here---- #!/bin/ksh # ls -ld * | grep '^l' | awk '{print $9}' > /tmp/linktmp.$$ for x in `cat /tmp/linktmp.$$` do if [ ! -e $x ] then echo "bogus link: $x" fi done ----cut here---- and here is one in Perl: ----cut here---- #!/usr/local/bin/perl use File::Find; find( \&wanted, '.' ); sub wanted { -l and not -e and print "bogus link: $File::Find::name\n"; } ----cut here---- - Tim Fritz (5) "test -s $file || ls -la $file" is the test you want in Bourne shell syntax. - Thomas Anders (6) Here you go: for link in `find . -type l ` do cat $link > /dev/null 2> /dev/null; if test $? -ne 0 then echo $link fi done - Chris Veenstra (7) Something like: find /dir -type l -exec ls -l {} \; -exec cat {} \>dev/null \; Should throw an error for the ones that are broken - Jim Malloy (8) Try this: for i in `ls -lc directory |awk '/^l/ {print $11}'` do echo $i if [ -r $i ] then echo "$i exists" fi done - Jaime Dela Rosa (9) Perl exists for a reason: #!/usr/bin/perl -w use strict; use File::Find; sub wanted { my $curfil = $_; my $curdir = $File::Find::dir; if ( ! -l $curfil ) { return; } #Curfil is a symlink my $linkto = readlink($curfil); if ( -e $linkto ) { return; } #file it links to does not exist print "$curdir/$curfil is a broken link (pointing to $linkto)\n"; } #Start of script my $top = shift @ARGV or die "Please provide a starting directory"; find(\&wanted,$top); ---------------------------- Usage: link-test.pl / (one argument, the directroy to start the find in). - Thomas M. Payerle (10) Doing this in perl, you could do the following: #!/usr/local/bin/perl -w use File::Find; find(\&wanted, '/dir'); sub wanted { return unless -l $File::Find::name; # Check only symbolic links unless (stat($File::Find::name)){ # If the file can't be stat'd print "Bad link for $File::Find::name\n"; } } - Dylan Northrup _______________________________________________ sunmanagers mailing list sunmanagers@sunmanagers.org http://www.sunmanagers.org/mailman/listinfo/sunmanagersReceived on Tue Apr 30 12:22:38 2002
This archive was generated by hypermail 2.1.8 : Thu Mar 03 2016 - 06:42:41 EST