Wednesday, October 12, 2011

Perl script to find Broken Symbolic links

Creating Symbolic links across filesystem are very handy but at the same time, they can be a real pain when they got broken. At my work I often seen Developers wasting their time in fixing application issues, which was fundamentally caused by broken symbolic links. So I came out with this script.

Upon execution of this script, it will prompt you to enter the filesystem paths as parameters. Once done, it will report all the broken symbolic links with count number.

I used the Perl module File::Find (comes default with any Perl package) for traversing through all the filenames in the specified directories and report the broken links. For each file it finds, it calls the &wanted subroutine, which in turn uses the Stat function to match the symbolic link files which are broken. To be honest, I grabbed this logic from an online book on Perl programming.

Supported platforms: Any Unix platform with Perl version 5.x installed.

EXAMPLE
[root@hostxyz opt]# perl check_broken_link.pl

Enter the filesystem path (like /etc /opt /var) : /var /etc /usr /home
Disconnected Link => /var/lib/jbossas/server/production/lib/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar
Disconnected Link => /var/lib/jbossas/server/default/lib/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar
Disconnected Link => /etc/alternatives/jaxws_api -> /usr/share/java/glassfish-jaxws.jar
Disconnected Link => /etc/alternatives/jaxws_2_1_api -> /usr/share/java/glassfish-jaxws.jar
Disconnected Link => /etc/alternatives/jaxb_2_1_api -> /usr/share/java/glassfish-jaxb.jar
Disconnected Link => /etc/alternatives/jaxb_api -> /usr/share/java/glassfish-jaxb.jar
Disconnected Link => /usr/share/java/jaxws_api.jar -> /etc/alternatives/jaxws_api
Disconnected Link => /usr/share/java/jaxb_api.jar -> /etc/alternatives/jaxb_api
Disconnected Link => /usr/share/java/jaxws_2_1_api.jar -> /etc/alternatives/jaxws_2_1_api
Disconnected Link => /usr/share/jbossas/client/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar

Total number of Disconnected links: 10
[root@hostxyz opt]# 

SCRIPT

#!/usr/bin/perl
use File::Find ();
use vars qw/*name *dir *prune/;
my ($cnt,$i,$cnt_sub) = (0,0,0);
print "\n";
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
print "Enter the filesystem path (like /etc /opt /var) : ";
my $arr = <>;
chomp($arr);
print "\n";
my @inpts = split(/ /, $arr);


foreach(@inpts)
{

File::Find::find({wanted => \&wanted}, $inpts[$i] ); # Calling wanted subroutine which use stat function to match broken links
$cnt = $cnt_sub + $cnt;
$i++;
$cnt_sub = 0;
}
print "Total number of Disconnected links: $cnt \n\n";


sub wanted {
if (-l $_) {
@stat = stat($_);
if ($#stat == -1)
{
$flname = `ls -l $name`;
($flperm, $numlnk, $flown1, $flown2, $dt, $mnth, $tm1, $tm2, $cfnm, $ar, $dsfl) = split /\s+/, $flname;
print "Disconnected Link => $cfnm $ar $dsfl\n\n";
$cnt_sub++;
  }
 }
}