2014-12-07 53 views
0

我有一个脚本,它创建一个新目录,然后遍历不同(源)目录的所有内容,并在新目录中创建链接到每个元素源目录。脚本的相关部分是:Perl -e文件测试无法识别无效链接

use strict; 
use warnings; 
use Getopt::Long; 
use Cwd 'getcwd'; 
use Cwd 'realpath'; 
#... 
opendir ($LC, $source_dir) or die "Cannot open directory: '$source_dir': $!"; 

while ($entry = readdir $LC) { 
    next if $entry =~ /\A\.\.?\z/; 
    print "-I- Creating a link $entry\n"; 
    system "ln -s ".realpath("${source_dir}/${entry}")." ${new_dir}/$entry"; 
    die "-E- couldn't create link ${new_dir}/$entry ... exiting.\n" unless -e "${new_dir}/$entry"; 
} 

closedir $LC; 
#... 

当源目录中的某个文件是死链接时,就会出现问题。命令ln在新目录中创建一个名为/new_dir/dead_link的文件,它链接到/source_dir/deal_link,但由于/source_dir/deal_link链接到一个不存在的文件,因此-e命令将/source_dir/deal_link识别为不存在并调用die命令。

运行ls -ltr /new_dir/dead link给出:

lrwxrwxrwx 1 user ttt 44 Dec 7 07:40 /new_dir/dead_link -> /source_dir/dead_link 

我怎么能这样做,如果该文件存在,无论它链接到-e将只检查?

+0

那为什么说这个文件不存在,而ls表示存在? – SIMEL 2014-12-07 14:10:18

+0

@mpapec,请参阅编辑。另外,除非(-e“$ {source_dir}/$ {entry}”);'添加行'next'会导致循环跳过死链接,并且不会尝试复制它(这不是我所需要的,我需要目录是相同的)。 – SIMEL 2014-12-07 14:14:07

+1

你见过'-l' – 2014-12-07 14:16:09

回答

3

要计算一个符号链接为“现有”如果存在的话,不论该文件是否不是它指向同样存在,你可以这样做:如果指定的文件

(-e "$newdir/$entry" || -l "$newdir/$entry") 

-l测试返回true是一个符号链接,并不关心它链接的位置。但是对于任何不是符号链接的东西都会返回false,所以您仍然需要-e来处理其他类型的文件。

+0

不需要'-e'。只要'-l'将返回* false *如果名称不存在 – Borodin 2014-12-07 14:32:33

+1

@Borodin:但是如果它不是链接也会返回false – ysth 2014-12-07 17:52:58

+0

@ysth:但是他*知道*这是他刚创建的链接它。事实上,如果'ln -s'失败了,因为已经有一个名称为节点,那么他*不需要真正的值。 – Borodin 2014-12-07 18:10:33