如何关注和完整报告一系列符号链接?

时间:2009-03-17 20:52:43

标签: java php unix shell symlink

有哪些最好的工具/编程技术可以跟踪符号链接的复杂嵌套并在整个路径中完全捕获和报告每个符号链接,包括路径中间的那些(有关详细信息,请参见下文)< /强>

这是一个具体的例子。请考虑shell命令的以下输出

 ls -l /Library/Java/Home
 lrwxr-xr-x  1 root  admin  48 Feb 24 12:58 /Library/Java/Home -> /System/Library/Frameworks/JavaVM.framework/Home

ls命令可以让您知道文件/ Library / Java / Home文件是另一个位置的符号链接。但是,它不会让你知道它所指向的东西也是一个符号链接

ls -l /System/Library/Frameworks/JavaVM.framework/Home
lrwxr-xr-x  1 root  wheel  24 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Home -> Versions/CurrentJDK/Home

反过来,这不会让你知道指向文件的部分路径是一个符号链接。

ls -l /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK
lrwxr-xr-x  1 root  wheel  3 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK -> 1.5

其中,只是为了完成这个故事,是另一个符号链接

ls -l /System/Library/Frameworks/JavaVM.framework/Versions/1.5
lrwxr-xr-x  1 root  wheel  5 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Versions/1.5 -> 1.5.0

最后指着一个“真正的”文件夹。

是否有任何工具可以以某种方式(图形或普通旧文本)为您显示完整的链接链?我相信一个人可以自己编写脚本(如果你愿意的话,请你这样做并分享!),但这似乎充满了“哦,垃圾,边缘的情况。哦,废话,另一个边缘案例“。我希望有人已经去打扰了。

我做自由职业/合同工作,每个人都使用符号链接稍微不同,以便在Web服务器上安装他们的PHP应用程序。我的一半工作通常是不嵌套这个(不可避免的)未记录的层次结构,所以我们知道在哪里放置我们的新代码/模块。

5 个答案:

答案 0 :(得分:1)

Tcl有一个命令[文件类型$ filename],如果它是一个链接,它将返回“link”。它有另一个命令[文件链接$ filename],它将返回链接指向的内容。使用这两个命令,可以获取链接并按照链接进行操作,直到找到实际文件。

也许这样的事情在我脑海中浮出水面:

#!/usr/bin/tclsh

proc dereferenceLink {path {tree {}}} {
    if {[file type $path] == "link"} {
        set pointsTo [file link $path]
        if {[lsearch -exact $tree $path] >= 0} {
            lappend tree $path
            return "[join $tree ->] (circular reference)"
        } else {
            lappend tree $path
            return [dereferenceLink $pointsTo $tree]
        }
    } else {
        lappend tree $path
        return [join $tree "->"]
    }
}

puts [dereferenceLink [lindex $argv 0]]

您将获得如下输出:

  

foo-&GT;酒吧,&GT;巴兹

如果有循环链接,它将如下所示:

  

foo-&gt; bar-&gt; baz-&gt; foo(圆形   参考)

答案 1 :(得分:1)

如果你在循环中添加了一个print,那么这个python脚本会这样做:

http://mail.python.org/pipermail/python-ideas/2007-December/001254.html

答案 2 :(得分:1)

这是一个bash脚本,我把它们扔了一会儿才做到这一点。它找到了“&gt;”在ls输出中,指示用于遍历链接的符号链接。我不能保证在边缘情况下的完美行为(例如,为了避免循环,它是在遵循十个链接之后放弃的硬编码),但它对我来说效果很好。

#!/bin/bash 

function deref() {

    FILE="${1%/}"
    COUNT=0
    while [ -L "$FILE" ]; do
        TARGET=`ls -l "$FILE" | sed -e 's/^.*> //'`
        [ ${TARGET:0:1} == "/" ] || TARGET="`dirname $FILE`/$TARGET"

        # strip trailing slashes; -L cannot handle those
        FILE="${TARGET%/}"

        COUNT=$(( COUNT + 1 ))
        [ $COUNT -eq 10 ] && exit 1
    done
    echo $FILE

}

deref "$1"

答案 3 :(得分:0)

如果你只需要知道最终的指示物,那么php就有realpath功能可以做到这一点。

答案 4 :(得分:0)

在PHP中,您可以使用is_linkreadlink

使用示例:

function dereference_link($path) {
  $parts = array();
  foreach (explode(DIRECTORY_SEPARATOR, $path) as $part) {
    $parts[] = $part;
    $partial = implode(DIRECTORY_SEPARATOR, $parts);
    if (is_link($partial)) {
      $result = dereference_link(readlink($partial) . substr($path, strlen($partial)));
      array_unshift($result, $path);
      return $result;
    }
  }
  return array($path);
}