如何列出符号链接链?


Answers:


65

只需使用namei

$ namei d
f: d
 l d -> c
   l c -> b
     l b -> a
       d a

5
瓷砖。这是一个很酷的命令。投票
Tom O'Connor

这应该是可接受的答案,因为它显示了操作中要求的完整链接链。此外,它可用于列出类似于的整个目录ls。谢谢!
恐惧症患者,2016年

确实,重新审阅这篇文章和namei是一个很棒的命令!
Kalecser

与“哪个”命令一起使用以查找程序的实际用法:$ namei`which java`
pdem 17-4-4

18

readlink -e <link>

readlink [选项] ...文件

  • -e,--
    canonicalize -existing canonicalize通过递归跟随给定名称的每个组件中的每个符号链接,所有组件必须存在
$ mkdir testlink
$ cd testlink
pjb@pjb-desktop:~/testlink$ ln -s c b
pjb@pjb-desktop:~/testlink$ ln -s b a
pjb@pjb-desktop:~/testlink$ 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
pjb@pjb-desktop:~/testlink$ echo foo > c
pjb@pjb-desktop:~/testlink$ cat a
foo
pjb@pjb-desktop:~/testlink$ readlink -e a
/home/pjb/testlink/c

注意:readlink a本身返回b

注意#2:与find -l一起使用,可以很容易地用perl编写列出链的实用程序,但它也必须足够聪明以检测循环

如果您有循环,readlink将不会输出任何内容。我想这比卡住好。

pjb@pjb-desktop:~/testlink$ ln -sf a c
pjb@pjb-desktop:~/testlink$ 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
pjb@pjb-desktop:~/testlink$ readlink -e a
pjb@pjb-desktop:~/testlink$ # (note: no output)

在OS X:brew install coreutilsgreadlink -e <link>
何塞·阿尔班

3

这是Bash中的递归函数:

chain() { export chain; local link target; if [[ -z $chain ]]; then chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; chain+=" -> $target"; chain "$target"; return; done; echo "$chain"; unset chain; }

在多行中:

chain() {
    export chain
    local link target
    if [[ -z $chain ]]
    then
        chain="$1"
    fi
    link=$(stat --printf=%N "$1")
    while [[ $link =~ \-\> ]]
    do
        target="${link##*\`}"
        target="${target%\'}"
        chain+=" -> $target"
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target"
        return
    done
    echo "$chain"
    unset chain
}

例子:

$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a

它要求stat(1)某些系统上可能不存在该功能。

如果名称包含反引号,单引号或“->”,它将失败。它陷入了一个具有symlink循环的循环中(可以使用Bash 4中的关联数组来解决)。它导出一个称为“链”的变量,而不管其是否已被使用。

可能还有其他问题。

编辑:

修复了一些相对符号链接的问题。有些仍然不起作用,但是下面的版本不需要链接的目标存在。

添加了使用readlink的版本:

chain ()
{
    export chain;
    local target;
    if [[ -z $chain ]]; then
        chain="$1";
    fi;
    target=$(readlink "$1");
    while [[ $target ]]; do
        chain+=" -> $target";
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target";
        return;
    done;
    echo "$chain";
    unset chain
}

我已经测试了您的脚本,它确实可以工作,但是我更喜欢简单的方法,因此即使不完整,我也接受了其他答案。
Kalecser 2010年

1
不错的脚本。有时我想看整个链,而readlink似乎并没有显示出来。Ubuntu上的Java是:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski 2010年

0

您可以使用类似的东西对namei的输出进行后处理,awk或者grep只获得所需的行:

namei d | awk '$1=="l"'

要么

namei d | egrep -e "->"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.