我如何跟踪并完整报告符号链接链?

发布于 2024-07-15 09:33:26 字数 1347 浏览 3 评论 0原文

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

这是一个具体的例子。 考虑 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 应用程序时使用的符号链接都略有不同。 我的一半工作通常是解除这种(不可避免的)未记录的层次结构的嵌套,以便我们知道将新代码/模块放在哪里。

What are the best tools/programming-techniques for following a complicated nesting of symlinks and completely capturing and reporting on every symlink along the way, including those in the middle of a path (See below for more info).

Here's a specific example. Consider the following output from a shell command

 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

The ls command lets you know that the file /Library/Java/Home file is a symlink to another location. However, it doesn't let you know that the thing it's pointing to is also a symlink

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

This, in turn, doesn't let you know that part of the path of the pointed to file is a symlink.

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

Which, just to complete this tale, is another symlink

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

Finally pointing at a "real" folder.

Are there any tools that can visualize the full chain of links for you in some way (either graphically or plain old text)? I'm sure one could script this themselves (and if you want to, please do it and share!), but it seems like the kind of thing that would be fraught with "oh, crap, edge case. Oh, crap, ANOTHER edge case". I'm hoping someone's already gone to the bother.

I do freelance/contract work, and everyone uses symlinks slightly differently to install their PHP applications on a web-server. Half my job is usually un-nesting this (inevitably) undocumented hierarchy so we know where to put our new code/modules.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

回忆追雨的时光 2024-07-22 09:33:26

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->bar->baz

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

foo->bar->baz->foo(循环
参考)

Tcl has a command [file type $filename] that will return "link" if it's a link. It has another command [file link $filename] that will return what the link points to. With those two commands it's possible to take a link and follow the links until you get to an actual file.

Perhaps something like this off the top of my head:

#!/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]]

You'll get output that looks like:

foo->bar->baz

If there's a circular link it will look like:

foo->bar->baz->foo (circular
reference)

薄荷梦 2024-07-22 09:33:26

如果您在循环内添加一个 print ,这个 python 脚本就可以做到这一点:

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

This python script would do it, if you added a single print inside the loop:

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

煮酒 2024-07-22 09:33:26

这是我不久前编写的一个 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"

Here's a bash script I threw together a while back to do exactly this. It finds the ">" in the ls output that indicates a symlink to walk the links. I can't vouch for perfect behavior in edge cases (it's hard coded to give up after following ten links in order to avoid loops, for example), but it's worked well for me.

#!/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"
朦胧时间 2024-07-22 09:33:26

在 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);
}

In PHP, you can use is_link and readlink.

Example usage:

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);
}
拿命拼未来 2024-07-22 09:33:26

如果您只需要知道最终的所指对象,php 有 realpath 函数可以做到这一点。

If you just need to know the ultimate referent, php has the realpath function which can do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文