I would like to remove a broken symlink in a directory using Perl.
In my mind I just had to list the file of a directory and test is this a symlink (-l) and if it returns false just unlink it.
But it appears that when using readir to list all files my broken symlinks are not recoganized as a file. Because my link is pointing to nothing I understand why.
All the file in $myDir are symlinks, either valid or broken.
When I display @files I only get a list of valid symlink.
opendir DIR, $myDir;
my @files = grep(/$regexp/,readdir(DIR));
closedir DIR;
print "filenames : @files\n";
There are two main relevant system calls,
stat()andlstat(). Thelstat()call will tell you that it is a symlink (but on other files, behaves the same asstat()). This allows you to determine that the name is a symlink. Thestat()system call follows a symlink to its end, and tells you about the file (or directory) at the end of the link. If thestat()call fails on the symlink, then the symlink is broken or you’re trying to access a directory or file where you have no permission.The Perl file test operators include
-lto detect whether a name is a symlink. You can use the Perl functionsstatandlstatexplicitly. Between these, you should be able to sort out whether a symlink is broken or not – but you should probably plan to write a function to do the job.You probably don’t need to use the
readlinkPerl function. Beware the underlying systemreadlink()call; it does not return a null-terminated string!It is interesting that neither Perl nor its POSIX module supports the
realpath()function. However, the PathTools module does support it. Ifrealpathfails, on a symlink, the symlink is non-functional (aka broken).