【问题标题】:"tracing" version of readlink(1)readlink(1) 的“跟踪”版本
【发布时间】:2013-02-20 10:07:18
【问题描述】:

我想要一个“readlink -f”版本,它可以跟踪它执行的每个单独的符号链接解析。比如:

$ linktrace /usr/lib64/sendmail
/usr/lib64 -> lib
/usr/lib/sendmail -> ../sbin/sendmail
/usr/sbin/sendmail
$ 

我知道我过去在 linux 上使用过这个实用程序,并且当时还记得当时想“这个工具的名称完全不直观,我会忘记它”。嗯,这一天已经到来了。

【问题讨论】:

  • 不确定这是否是您要求的,但有一个 libc 函数 realpath 和一个同名的 GNU 工具。

标签: linux command-line utility symlink-traversal


【解决方案1】:

没有人获胜。正确答案是“namei”。

【讨论】:

    【解决方案2】:

    This Serverfault answer(在 Bash 中)可能会有所帮助(尽管它并不声称可以处理所有边缘情况)。

    【讨论】:

    • 与 Ben Jackson 的尝试类似,这些脚本仅解析路径中的最后一个符号链接,而不是之前的任何“目录级”符号链接。 "chain /usr/lib64/sendmail" 只打印 "/usr/lib64/sendmail -> ../sbin/sendmail" 这还不够。
    【解决方案3】:

    代码高尔夫有人吗?

    #!/usr/bin/perl
    
    use File::Spec;
    my $g;
    my $f = shift;
    while (1) {
        print $f;
        $g = readlink($f);
        last unless defined $g;
        printf " -> %s\n", $g;
        $f =~ s,/[^/]*$,,;
        $f = File::Spec->rel2abs($g, $f);
    }
    print "\n";
    

    好的,这个怎么样:

    #!/usr/bin/perl
    
    use File::Spec;
    
    sub r {
        my ($p, $s) = @_;
        my $l = readlink $p;
        if ($l) {
            printf "%s -> %s\n", $p, $l;
            $p =~ s,/[^/]*$,,;
            r("",File::Spec->rel2abs($l,$p) . $s)
        } else {
            $s =~ s!^(/?[^/]+)(.*)! r($p.$1, $2) !e;
        }
    }
    r("",shift);
    

    输出与描述的不太一样,但可以理解。并挖掘那个疯狂的递归可执行正则表达式替换!

    【讨论】:

    • 不处理 /usr/lib64 -> /usr/lib 步骤。
    • 我专门添加了代码 (rel2abs) 来处理这种情况并对其进行了测试。不知道你的意思...
    • /usr/lib64 也是一个符号链接。它指向 /usr/lib。它需要作为解决以它开头的任何路径的一部分来解决。您的脚本仅解析结束符号链接。 “linktrace.BenJ /usr/lib64/sendmail”的最终结果是“/usr/lib64/../sbin/sendmail”,这是不够的。
    • 在大多数系统上,/usr/lib64 不是符号链接。 (是的,周围有一些发行版会做这些奇怪的事情。不过根据features.opensuse.org/308372,这是违反标准的。)
    猜你喜欢
    • 2013-05-25
    • 2017-03-15
    • 1970-01-01
    • 2011-01-22
    • 2012-08-02
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多