ぶら下がっているシンボリックリンクがどのような動作を示すかを簡単にテストしましたが、シンボリックリンクの定義は私が理解できる限りであることがわかりました
- -l は true を返します
- -e は undef # を返します。なぜなら、-e はリンクされたファイルに作用するからです
したがって、File::Find::Rule を使用してやろうとしていることは比較的単純です。
#!/usr/bin/perl
use strict;
use warnings;
use File::Find::Rule ();
my @files = File::Find::Rule->symlink->exec(sub{ !-e $_ })->in('/tmp/test');
print "$_,\n" for @files;
このコード スニペットは、壊れたシンボリック リンクをすべて検出することができました。
私が実行したテストでこれを結論付けたい場合:
#!/usr/bin/perl
use strict;
use warnings;
use File::Path ();
use Carp ();
my $testdir = "/tmp/test";
# Generating test
# Making Dirs
dirmk($_)
for (
qw(
/realdir/
/deleteddir/
)
);
#"Touching" some files
generate($_)
for (
qw(
/realfile
/deletedfile
/realdir/realfile
/realdir/deletedfile
/deleteddir/afile
)
);
# Symlink them
{
lns( '/realfile', '/realfile_symlink' );
lns( '/deletedfile', '/deletedfile_symlink' );
lns( '/realdir', '/realdir_symlink' );
lns( '/deleteddir', '/deleteddir_symlink' );
lns( '/realdir/realfile', '/realdir_realfile_symlink' );
lns( '/realdir/deletedfile', '/realdir_deletedfile_symlink' );
lns( '/deleteddir/afile', '/deleteddir_file' );
}
# Make the deletions
del($_)
for (
qw(
/deletedfile
/deleteddir/afile
/realdir/deletedfile
/deleteddir/
)
);
statify($_)
for (
'', qw(
/realfile
/realfile_symlink
/deletedfile_symlink
/realdir
/realdir_symlink
/deleteddir_symlink
/realdir/realfile
/realdir_realfile_symlink
/realdir_deletedfile_symlink
/deleteddir_file
)
);
sub statify {
my $fn = $testdir . shift;
printf(
"r: %3s e: %3s s: %3s f: %3s d: %3s l: %3s | %s \n",
-r $fn || 0,
-e $fn || 0,
-s $fn || 0,
-f $fn || 0,
-d $fn || 0,
-l $fn || 0,
$fn
);
}
sub generate {
my $fn = $testdir . shift;
open my $fh, '>', $fn or Carp::croak("Error Creating $fn $! $@");
print $fh "This is $fn \n";
close $fh or Carp::carp("Error on close for $fn $! $@");
return;
}
sub lns {
my $x = $testdir . shift;
my $y = $testdir . shift;
if ( -e $y ) {
unlink $y;
}
symlink $x, $y or Carp::croak("Error ln $x => $y , $! $@");
}
sub del {
my $fn = $testdir . shift;
if ( -f $fn ) {
unlink $fn;
}
if ( -d $fn ) {
rmdir $fn;
}
}
sub dirmk {
my $fn = $testdir . shift;
File::Path::mkpath($fn);
}
そして、ここに出力がありました:
r: 1 e: 1 s: 220 f: 0 d: 1 l: 0 | /tmp/テスト
r: 1 e: 1 s: 28 f: 1 d: 0 l: 0 | /tmp/test/実ファイル
r: 1 e: 1 s: 28 f: 1 d: 0 l: 1 | /tmp/test/realfile_symlink
r: 0 e: 0 s: 0 f: 0 d: 0 l: 1 | /tmp/test/deletedfile_symlink
r: 1 e: 1 s: 60 f: 0 d: 1 l: 0 | /tmp/test/realdir
r: 1 e: 1 s: 60 f: 0 d: 1 l: 1 | /tmp/test/realdir_symlink リンク
r: 0 e: 0 s: 0 f: 0 d: 0 l: 1 | /tmp/test/deleteddir_symlink
r: 1 e: 1 s: 36 f: 1 d: 0 l: 0 | /tmp/test/realdir/realfile
r: 1 e: 1 s: 36 f: 1 d: 0 l: 1 | /tmp/test/realdir_realfile_symlink
r: 0 e: 0 s: 0 f: 0 d: 0 l: 1 | /tmp/test/realdir_deletedfile_symlink
r: 0 e: 0 s: 0 f: 0 d: 0 l: 1 | /tmp/test/deleteddir_file