在服务器故障,How to list symbolic link chains?(不是我的问题)谈论列出所有符号链接并跟随它们.为了使这个可行,我们首先考虑一个目录.
我想写一个实用程序的简短实用程序.将符号链接中的对放入哈希中然后处理哈希看起来很容易.
但后来我可能有类似的东西:
ls -l total 0 lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:03 c -> a lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:17 trap -> b lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:17 x -> y lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:17 y -> b
很明显a-> b-> c是一个循环,并且该陷阱指向一个循环,但要知道x指向一个循环,我需要跟随一点.
一个哈希表示是:
a => b b => c c => a trap => b x => y y => b
但是一旦我知道循环是什么,反向表示更好地将循环标记为坏起点.
所以这里有一些问题:
>哈希是表示符号链接的最佳结构吗?
>什么是分离文件系统图形以将循环组件从树组件分配到具有循环类型片段的树枝的最佳方法?
>是否有比从所有起点手动搜索所有循环更好的算法?
>从图论理论的角度来看 – CPAN中的这种事情已经存在了吗?如果没有,有什么好帮手模块?
解决方法
您可以在CPAN上使用
Graph模块,如下所示:
#! /usr/bin/perl use warnings; use strict; use Graph; my $g = Graph->new; my $dir = @ARGV ? shift : "."; opendir my $dh,$dir or die "$0: opendir $dir: $!"; while (defined(my $name = readdir $dh)) { my $path = $dir . "/" . $name; if (-l $path) { my $dest = readlink $path; die "$0: readlink $path: $!" unless defined $dest; $g->add_edge($name => $dest); } else { $g->add_vertex($name); } } my @cycle = $g->find_a_cycle; if (@cycle) { $" = ' -> '; #" # highlighting error print "$0: $dir: at least one cycle: @cycle\n"; } else { print "$0: $dir: no cycles\n"; }
例如,在与您的问题中的结构类似的目录中,输出是
$../has-cycle ../has-cycle: .: at least one cycle: c -> a -> b