如何在目录树中查找所有符号链接?

391

我正试图查找我的网站目录树中的所有符号链接。我知道可以使用find命令来实现这一点,但我无法弄清如何递归检查目录。

我已经尝试了以下命令:

find /var/www/ -type l

…后来我发现/var/www中的内容是符号链接,所以我将命令更改为:

find -L /var/www/ -type l

运行需要一些时间,但是我没有得到任何匹配结果。

如何让它检查子目录?

8个回答

415
这将递归遍历/path/to/folder目录,并仅列出符号链接。
ls -lR /path/to/folder | grep '^l'

如果你的意图是要跟随符号链接,你应该使用你的find命令,但是你应该包括-L选项;事实上,find的手册页上写道:
   -L     Follow symbolic links.  When find examines or prints information
          about files, the information used shall be taken from the  prop‐
          erties  of  the file to which the link points, not from the link
          itself (unless it is a broken symbolic link or find is unable to
          examine  the file to which the link points).  Use of this option
          implies -noleaf.  If you later use the -P option,  -noleaf  will
          still  be  in  effect.   If -L is in effect and find discovers a
          symbolic link to a subdirectory during its search, the subdirec‐
          tory pointed to by the symbolic link will be searched.

          When the -L option is in effect, the -type predicate will always
          match against the type of the file that a symbolic  link  points
          to rather than the link itself (unless the symbolic link is bro‐
          ken).  Using -L causes the -lname and -ilname predicates  always
          to return false.

然后试试这个:
find -L /var/www/ -type l

这可能会起作用:我在find手册中找到了这个钻石:如果你正在使用-type选项,你必须将其更改为-xtype选项。
          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

然后:

find -L /var/www/ -xtype l

1
谢谢,这可能有效,但我刚刚注意到/var/www/的内容已经是符号链接了,而这似乎不会递归到这些目录中。 - hafichuk
5
@hafichuk 请查看我回答中的最终编辑(find -L /var/www/ -xtype l)。在你的 find 命令中使用 -xtype 而不是 -type 应该能解决问题。祝你好运! - ztank1013
5
如果您还想处理“隐藏”的点文件夹,请将其更改为ls -laR /path/to/folder | grep ^l - wimvds
5
谢谢!但是这只显示链接的名称而不是它们的位置。 - Kostanos
10
在Mac OSX(10.9)中,-xtype参数不可用。使用find . -type l命令似乎会进行递归检查。 - amertkara
显示剩余8条评论

384

一个命令,无需管道

find . -type l -ls

解释: 从当前目录 . 开始,查找所有的 -type l 符号链接并详细列出 -ls 信息。

简单明了...

在此基础上,以下是更多与符号链接有关的 find 命令:

查找指向特定目标的符号链接

find . -lname link_target

注意,link_target是一个可能包含通配符的模式。

查找损坏的符号链接

find -L . -type l -ls

-L选项指示find跟随符号链接,除非链接是断开的。

查找和替换断开的符号链接

find -L . -type l -delete -exec ln -s new_target {} \;

更多查找示例

这里可以找到更多find的示例:https://hamwaves.com/find/


8
如果您希望更加简洁,可以提到大多数版本的 find 命令都有一个 -ls 选项。因此,find . -type l -ls 应该等同于上面的命令。 - Bratchley
11
这篇回答比被接受的答案更好,因为它告诉你符号链接在目录树中的位置,尤其是在处理具有符号链接的复杂和深层次树时非常重要。 - Jesse Crossen
3
更好的是将问题接受为更好的答案。 - Lord_Dracon
5
这个答案比被采纳的答案更有用。此外,如果你想查找指向某个目录中文件的符号链接: find -lname '*/dir/*' -printf '%P -> %l\n'。值得一提的是,link_target是一个模式。 - x-yuri
3
这是我喜欢的回答类型。简单明了。谢谢。 - daparic
显示剩余2条评论

16

find默认已经具备递归查找功能:

[15:21:53 ~]$ mkdir foo
[15:22:28 ~]$ cd foo
[15:22:31 ~/foo]$ mkdir bar
[15:22:35 ~/foo]$ cd bar
[15:22:36 ~/foo/bar]$ ln -s ../foo abc
[15:22:40 ~/foo/bar]$ cd ..
[15:22:47 ~/foo]$ ln -s foo abc
[15:22:52 ~/foo]$ find ./ -type l
.//abc
.//bar/abc
[15:22:57 ~/foo]$ 

这可能是其中一个问题。 /var/www 中的所有文件都是符号链接。 find 默认会递归这些吗?我猜不会 ;) - hafichuk
是的,可能是为了避免循环。 - jman
我已经尝试使用“-L”标志来查找更新,但没有成功 - 有什么猜测吗? - hafichuk
完美的解决方案,并且它显示了链接的位置。谢谢! - Kostanos

10

如果您只想查看符号链接本身,可以使用以下命令:

find -L /path/to/dir/ -xtype l 

如果你想看它们目标的文件,只需添加ls即可。

find -L /path/to/dir/ -xtype l -exec ls -al {} \;

8

这是我迄今为止发现的最好的东西 - 它可以递归地显示当前目录中的符号链接,但不会跟随它们,以完整路径和其他信息显示:

find ./ -type l -print0 | xargs -0 ls -plah

输出结果大致如下:

lrwxrwxrwx 1 apache develop 99 Dec  5 12:49 ./dir/dir2/symlink1 -> /dir3/symlinkTarget
lrwxrwxrwx 1 apache develop 81 Jan 10 14:02 ./dir1/dir2/dir4/symlink2 -> /dir5/whatever/symlink2Target
etc...

2
fd 等同于 fd . -t l --print0 | xargs -0 ls -plah - OldBuildingAndLoan

1
请查找下面这个单行Bash脚本命令,以递归方式在任何基于Linux的操作系统中查找所有损坏的符号链接。
a=$(find / -type l); for i in $(echo $a); do file $i ; done |grep -i broken 2> /dev/null

1
您的命令可以是 find / -type l -exec file {} \; | grep -i broken 2>/dev/null。请注意,您可能会得到很多错误的结果。 - ingroxd

0
你可以安装“symlinks”包并使用该工具。
symlinks -rv "/path"

    -c == change absolute/messy links to relative
    -d == delete dangling links
    -o == warn about links across file systems
    -r == recurse into subdirs
    -s == shorten lengthy links (displayed in output only when -c not specified)
    -t == show what would be done by -c
    -v == verbose (show all symlinks)

悬挂链接是指那些已经失效的链接。


-2
我所做的是在我的bin目录中创建一个类似于别名的脚本。 例如,我有一个名为lsd的脚本 ls -l | grep ^d
你可以创建一个名为lsl的脚本 ls -lR | grep ^l
只需将它们chmod +x,就可以使用了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接