2010-02-23 24 views
8

在服務器故障,How to list symbolic link chains?(不是我的問題)談論列出所有的符號鏈接,並遵循它們。爲了實現這一點,我們首先考慮一個單獨的目錄。如何在Perl哈希中表示文件系統的符號鏈接?

我想寫一個簡短的工具來做到這一點。將符號鏈接的對放入散列並處理散列看起來很容易。

但後來我可能有類似:

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已經是這種東西了嗎?如果不是,那麼一些好幫手模塊是什麼?
+0

顯然也鼓勵提交示例代碼來解決問題。 – Paul 2010-02-23 17:36:42

+0

向我們展示您到目前爲止所嘗試的內容也受到鼓勵。 :) – 2010-02-23 21:34:37

+0

@brian Doh!我認爲這主要是別人的整潔問題,除了承認一些陷阱之外,並沒有試圖解決這個問題。 – Paul 2010-02-24 18:50:52

回答

7

有一個Graph模塊CPAN,你可能會在下面的使用:

#! /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
+0

感謝您發佈此信息。我打算查看圖表,瞭解我有的其他需求,並且仔細研究這些內容。 – Paul 2010-02-25 16:49:56

+0

@保羅不客氣!我很高興你覺得它有益。 – 2010-02-25 17:00:32

2

看看CPAN模塊File::Spec::Link。解析方法說它重複遍歷一個鏈接來查找鏈接的目標。

模塊的解決方法,有這樣一段話:

決心($鏈接)
   返回非鏈接最終鏈接到由$連接,通過反覆調用鏈接。如果鏈接無法解析,則返回undef

我已經使用此模塊來查找符號鏈接的目標,其目標又是符號鏈接等等。但我不確定這是否檢測到循環符號鏈接。

-1

您需要存儲的不僅僅是鏈接的名稱。要麼抓住inode號碼(如果你的FS支持的話)或其他一些獨特的方面。如果不存在,則考慮創建自己的,也許通過校驗名稱/創建/上次修改日期來創建。無論哪種方式,您都需要一些方法來唯一標識每個鏈接。我看到一些公用事業公司只是對鏈接數量(8到255之間)進行限制,並聲明任何超過此限制的事情都是一個循環,但我一直認爲這是「以廉價的方式」。 :)