代码之家  ›  专栏  ›  技术社区  ›  Alana Storm

如何跟踪和全面报告一系列符号链接?

  •  3
  • Alana Storm  · 技术社区  · 16 年前

    跟踪复杂的符号链接嵌套的最佳工具/编程技术是什么? 并完全捕获和报告沿途的每个符号链接,包括路径中间的符号链接(有关详细信息,请参阅下文) .

    下面是一个具体的例子。考虑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命令让您知道文件/库/爪哇/home文件是到另一个位置的Syrink。然而,它并不能让你知道它所指向的东西也是一个符号链接。

    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 回复  |  直到 16 年前
        1
  •  1
  •   Bryan Oakley    16 年前

    tcl有一个命令[file type$filename],如果是链接,它将返回“link”。它还有另一个命令[file 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->栏->baz

    如果有一个圆形链接,它将看起来像:

    foo->bar->baz->foo(圆形 参考文献)

        2
  •  1
  •   user23743    16 年前
        3
  •  1
  •   Marty Lamb    16 年前

    这是我花了一段时间拼凑出来的一个bash脚本。它在 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"
    
        4
  •  0
  •   troelskn    16 年前

    在PHP中,您可以使用 is_link readlink .

    示例用法:

    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);
    }
    
        5
  •  0
  •   Mat    13 年前

    如果您只需要知道最终的引用,php就可以 realpath 可以做到这一点的功能。