Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么';t文件::找到我的断开符号链接吗?_Perl_Symlink_File Find - Fatal编程技术网

Perl 为什么';t文件::找到我的断开符号链接吗?

Perl 为什么';t文件::找到我的断开符号链接吗?,perl,symlink,file-find,Perl,Symlink,File Find,我正在使用Perl的File::Find模块扫描文件、目录和链接。除此之外,我希望我正在编写的实用程序能够报告损坏的(用File::Find的说法是悬挂的)符号链接。理论上,这是通过创建一个子例程来支持的,该子例程将在发现断开的链接时调用,并使用适当值的哈希引用调用find方法,例如: my %options = ( wanted => \&ProcessFile, follow => 1, follow_skip

我正在使用Perl的File::Find模块扫描文件、目录和链接。除此之外,我希望我正在编写的实用程序能够报告损坏的(用File::Find的说法是悬挂的)符号链接。理论上,这是通过创建一个子例程来支持的,该子例程将在发现断开的链接时调用,并使用适当值的哈希引用调用
find
方法,例如:

my %options = (
   wanted            => \&ProcessFile,
   follow            => 1,
   follow_skip       => 2,
   dangling_symlinks => \&Dangling
);

find(\%options, @ARGV);

尽管故意创建了一个断开的链接来测试这一点,但File::Find never,ever调用了子例程
悬挂
。除此功能外,其他所有功能都正常工作,即按预期调用
ProcessFile
子文件,并遵循链接,等等。

在我的主目录中创建
test.pl

#!/usr/bin/perl

use File::Find;

my %options = ( wanted => \&ProcessFile,
                follow => 1,
                follow_skip => 2,
                dangling_symlinks => \&Dangling );

find(\%options, @ARGV);

sub ProcessFile {
  print "ProcessFile ($File::Find::name in $File::Find::dir)\n";
}

sub Dangling {
  my ($name, $dir) = @_;
  print "Dangling ($name in $dir)\n";
}
然后:

$chmod 755 test.pl $mkdir/tmp/findtest $cd/tmp/findtest $ln-s/tmp/doesnotexist链接 $~/test.pl。 结果:

ProcessFile (. in .) Dangling (linkylink in ./) ProcessFile (./linkylink in .) 进程文件(.in.) 悬挂(链接链接入/) 进程文件(./linklink-in.) 我喜欢在使用中看到,但在这里没有区别

尽管如此

$ mkdir test
$ cd test
$ ln -s a b
$ perl -w -MFile::Find -e'find({wanted=>sub{print"wanted $_\n"},dangling_symlinks=>sub{print"dangling $_[0] in $_\n"},follow=>1},".")'
wanted .
dangling b in .
wanted b
对我有用

什么是perl-MFile::Find-e'print“$File::Find::VERSION\n”

更新 通过查看Perl的RT,我发现。它显然会影响
File::Find
1.07及更早版本,它与Perl5.8.7及更早版本(以及5.9.x开发系列中的5.9.1及更早版本)捆绑在一起


我建议您说服您的系统管理员更新Perl,或者至少更新一些模块(并在他们进行更新时添加
File::Find::Rule
),但如果做不到这一点,您可以自己制作并将更新的模块放在那里。

我做了一个快速测试,以确定悬挂符号链接会出现什么行为,事实证明,符号链接的定义是我所能理解的

  • -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/test r: 1 e: 1 s: 28 f: 1 d: 0 l: 0 | /tmp/test/realfile 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 r:1E:1S:220F:0D:1L:0 |/tmp/测试 r:1e:1s:28f:1d:0l:0 |/tmp/test/realfile r:1e:1s:28f:1d:0l:1 |/tmp/test/realfile\u符号链接 r:0e:0s:0f:0d:0l:1 |/tmp/test/deletedfile\u符号链接 r:1e:1s:60f:0d:1l:0 |/tmp/test/realdir r:1e:1s:60f:0d:1l:1 |/tmp/test/realdir_符号链接 r:0e:0s:0f:0d:0l:1 |/tmp/test/deleteddir\u符号链接 r:1e:1s:36f:1d:0l:0 |/tmp/test/realdir/realfile r:1e:1s:36f:1d:0l:1 |/tmp/test/realdir\u realfile\u符号链接 r:0e:0s:0f:0d:0l:1 |/tmp/test/realdir\u deletedfile\u符号链接 r:0e:0s:0f:0d:0l:1 |/tmp/test/deleteddir_文件
    您使用的是什么版本的Perl?我使用的是5.8.0,但它对我不起作用。悬挂子例程(在我的代码中与您的非常相似)从未被调用。为了测试它,我创建了一个目录,使用ln-s链接到它,然后删除了该目录。我试过了……你可以把File::Fine::Rule的源代码放在你的脚本中。你能添加你的Perl版本吗? r: 1 e: 1 s: 220 f: 0 d: 1 l: 0 | /tmp/test r: 1 e: 1 s: 28 f: 1 d: 0 l: 0 | /tmp/test/realfile 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