如何检测Perl中符号链接是否被破坏?

我想用Perl删除目录中的一个破碎的符号链接

在我看来,我只需要列出一个目录的文件,并testing这是一个符号链接(-l),如果它返回false只是取消它的链接。

但是看起来,当使用readir来列出所有文件时,我的符号链接不会被识别为一个文件。 因为我的链接没有指向我明白为什么。

那么 :如何检测Perl中的符号链接是否被破坏?

谢谢,

UPDATE

$ myDir中的所有文件都是符号链接,无论是有效还是破坏。 当我显示@文件时,我只能得到一个有效的符号链接列表。

opendir DIR, $myDir; my @files = grep(/$regexp/,readdir(DIR)); closedir DIR; print "filenames : @files\n"; 

有两个主要的相关系统调用stat()lstat()lstat()调用会告诉你这是一个符号链接(但在其他文件上,其行为与stat()相同)。 这使您可以确定该名称是符号链接。 stat()系统调用遵循一个符号链接到末尾,并告诉你链接末尾的文件(或目录)。 如果stat()调用在符号链接上失败,那么符号链接被破坏,或者您尝试访问没有权限的目录或文件。

Perl 文件测试运算符包括-l来检测名称是否是符号链接。 你可以明确地使用Perl函数statlstat 。 在这些之间,你应该能够理清符号链接是否被破坏 – 但是你也许应该计划写一个函数来完成这个工作。

您可能不需要使用readlink Perl函数。 当心系统的readlink()调用; 它不会返回以null结尾的字符串!

有趣的是Perl和POSIX模块都不支持realpath()函数。 但是, PathTools模块确实支持它。 如果实际realpath失败,则在符号链接上,符号链接不起作用(又名破碎)。

结合lstatstat

 say "dangling link at $fn" if (lstat $fn and not stat $fn); 

更新 :它适用于我…

 salva@topo:~/t/dl$ perl -E 'opendir $dh, "."; say $_ for grep { !stat $_ and lstat $_ } readdir $dh' foo salva@topo:~/t/dl$ ls -l total 0 -rw-rw-r-- 1 salva salva 0 2011-07-05 12:34 f lrwxrwxrwx 1 salva salva 11 2011-07-05 12:00 fii -> /etc/shadow lrwxrwxrwx 1 salva salva 12 2011-07-05 11:59 foo -> /etc/hjdkshf 

以下是我用来删除断开的链接的一些代码:

 chdir $dir or die; opendir(DIR, '.') or die; foreach my $link (readdir DIR) { next unless -l $link and not -e readlink($link); print "Removing broken link $link\n"; unlink $link; } closedir DIR; 

请注意,包含链接的目录是当前目录是很重要的。 readdir只返回文件名,链接可能是相对的。

检查是否有符号链接(如果符号链接符号链接,只检查最高层):

 use strict; use warnings; use autodie; opendir my $dirh, '.'; while (my $file = readdir $dirh) { if ( -l $file ) { my $target = readlink $file; if ( ! -e $target && ! -l $target ) { print "$file -> $target broken\n"; } } } 

使用readlink()stat()结果。

使用内置的Perl glob函数? 举些例子:

  @files = <*>; foreach $file (@files) { print $file . "\n"; } 

对于特定的$dir

  @files = <$dir*>; foreach $file (@files) { print $file . "\n"; }