简体   繁体   English

如何在Perl哈希中表示文件系统的符号链接?

[英]How can I represent a file system's symbolic links in a Perl hash?

On Server Fault, How to list symbolic link chains? 在服务器故障, 如何列出符号链接链? (not my question) talks about listing all the symbolic links and following them. (不是我的问题)讨论列出所有符号链接并跟随它们。 To make this doable, let's consider a single directory at first. 为了使这个可行,我们首先考虑一个目录。

I want to write a short utility that does this. 我想编写一个实用程序的简短实用程序。 It looks easy to put pairs from symbolic links into a hash and then process the hash. 将符号链接中的对放入哈希中然后处理哈希看起来很容易。

But then I might have something like: 但后来我可能有类似的东西:

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

where it is obvious that a->b->c is a loop, and that trap points into a loop, but to know x points into a loop I need to follow a bit. 很明显a->b->c是一个循环,并且该陷阱指向一个循环,但要知道x指向一个循环,我需要跟随一点。

One hash representation is: 一个哈希表示是:

a => b
b => c
c => a
trap => b
x => y
y => b

But the reverse representation is better for marking loops to bad starting points, once I know what the loops are. 但是一旦我知道循环是什么,反向表示更好地将循环标记为坏起点。

So here's some questions: 所以这里有一些问题:

  • Is a hash the best structure to represent symbolic links? 哈希是表示符号链接的最佳结构吗?
  • what's the best way to separate the graph of the file system to tell the loopy components from the tree components to the twig with a loop type pieces? 什么是分离文件系统图形的最佳方法,将循环组件从树组件告诉树枝与循环类型的碎片?
  • Is there a better algorithm than manually searching for all the loops from all the starting points? 是否有比从所有起点手动搜索所有循环更好的算法?
  • From a graph-theory perspective -- is this sort of thing in the CPAN already? 从图论理论的角度来看 - CPAN中的这种事情已经存在了吗? If not, what are some good helper modules? 如果没有,有什么好帮手模块?

There's a Graph module on CPAN that you might use as in the following: 您可以在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";
}

For example, in a directory similar in structure to the one in your question, the output is 例如,在与您的问题中的结构类似的目录中,输出为

$ ../has-cycle 
../has-cycle: .: at least one cycle: c -> a -> b

Have a look at the CPAN module File::Spec::Link . 看看CPAN模块File :: Spec :: Link The resolve method says that it traverses a link repeatedly to find the linked target. resolve方法表示它反复遍历链接以查找链接目标。

The resolve method of the module has this to say: 该模块的解析方法有这样的说法:

resolve($link) 决心($链接)
Returns the non-link ultimately linked to by $link, by repeatedly calling linked. 通过反复调用linked返回最终链接到$ link的非链接。 Returns undef if the link can not be resolved 如果无法解析链接,则返回undef

I had used this module to find a target of symbolic link whose target was in turn a symlink and so on. 我曾使用这个模块来找到符号链接的目标,其目标又是一个符号链接,依此类推。 But I am not sure if this detects the cyclic symbolic links. 但我不确定这是否检测到循环符号链接。

You need to store more than just the name of the link. 您需要存储的不仅仅是链接的名称。 Either grab the inode number (if your FS supports that) or some other unique aspect. 获取inode编号(如果您的FS支持)或其他一些独特的方面。 If one doesn't exist, then consider creating your own, maybe by checksumming the name/create/last-modified date. 如果不存在,则考虑创建自己的,可能通过校验名称/创建/最后修改日期。 Either way, you need some way to uniquely identify each link. 无论哪种方式,您都需要一些方法来唯一标识每个链接。 I've seen some utilities that simply put a limit on the number of links (between 8 and 255) and declare anything that exceeds this limit a loop, but I always considered that as "taking the cheap way out". 我已经看到一些实用程序只是限制链接数量(8到255之间)并声明任何超过此限制的循环,但我一直认为这是“以便宜的方式”。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM