Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Remove broken symlinks with IO::All

by Dylan (Monk)
on Aug 12, 2006 at 02:29 UTC ( #566997=snippet: print w/replies, xml ) Need Help??

This is a short script using IO::All to remove broken symlinks.

Note, it has to redefine the readlink() method, because as of version 0.35 of IO::All, readlink doesn't handle relative symlinks.

IO::All sure makes my life easier!

use strict;
use warnings;
use IO::All::Link; # Because we redefine readlink()...
use IO::All;

my $file = shift @ARGV || '.';
my @ios = ( io($file) );

while (my $io = shift @ios) {
    if ($io->is_dir) {
        push @ios, $io->all;
    } elsif ($io->is_link and not $io->readlink->exists) {
        print "$io is broken, removing.\n";

# this has been submitted as a patch to IO::All...
no warnings 'redefine';
sub IO::All::Link::readlink {
    my $io = shift;
    my $path = CORE::readlink($io->name);
    unless (File::Spec->file_name_is_absolute($path)) {
        $path = File::Spec->join($io->filepath, $path);
Replies are listed 'Best First'.
Re: Remove broken symlinks with IO::All
by graff (Chancellor) on Aug 13, 2006 at 03:30 UTC
    Very nice -- thank you, especially for handling relative links. I would just add a couple things, at first glance:

    1. When deleting a stale symlink, the report about the deletion should include the stale target path.

    2. It would be prudent to have a "-n" mode (no deletions, just report the paths and targets of stale links).

    Sometimes, when you detect a stale link, it could be that you would rather just change the target (e.g. because the target was moved to a new disk volume), or it could be that the target is only "temporarily" inaccessible (e.g. because an nfs or samba server is down).

    At the very least, provide enough logging so that it's easy to re-install a deleted link, in case deletion was the wrong thing to do. Better yet, simply report stale links and their targets, and give the user a chance to decide what the appropriate action should be (delete it, replace it, or make sure a given network disk volume comes back online).

    Here's a script I wrote a while back to list all links (good and bad, including link chains:  link.1 -> link.2 -> ... -> data.file ). This was done before I knew about IO::All, so it uses unix "find" instead.

      It's mostly a replacement for 'cleanlinks', which comes with Xorg (and Xfree86, too). :)
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://566997]
[Cosmic37]: now I have tried another blunder - can anyone explain why I am such a dunderhead?
[Cosmic37]: if ( $line =~ /$mydt/ ) { print $line; }
[Cosmic37]: I try to match successive date times stored in variable $mydt
[Cosmic37]: I guess it is searching for the string "$mydt"
[Corion]: Indeed cool, erix ;)
[Cosmic37]: rather than the value of $mydt which is a date time strong such as 2016-01-01 12:30:56
[Corion]: Cosmic37: No, but maybe $mydt doesn't contain what you think it does, or it contains characters that are special in a regular expression? Try if( $line =~ /\Q$mydt\E/) { ... for a literal match
[Cosmic37]: I mean string grrr
[Corion]: Maybe add an else branch in which you print what the values of $line and $mydt are?
[Cosmic37]: ah thank you I will try

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (11)
As of 2017-06-29 16:58 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (673 votes). Check out past polls.