有没有办法找到所有不指向的符号链接?
find ./ -type l
会给我所有的符号链接,但不区分去某处的链接和不去某处的链接。
我目前正在做:
find ./ -type l -exec file {} \; | grep broken
但我想知道存在哪些替代解决方案。
答案1
我强烈建议不是用于find -L
任务(请参阅下面的解释)。以下是执行此操作的一些其他方法:
如果你想使用“纯粹
find
”的方法,并假设 的 GNU 实现find
,它应该看起来像这样:find . -xtype l
(
xtype
是在取消引用的链接上执行的测试)可移植(尽管效率较低),您也可以
test -e
从find
命令中执行:find . -type l ! -exec test -e {} \; -print
甚至一些
grep
技巧可能会更好(即,更安全) 比find -L
,但不完全像问题中提出的那样(在整个输出行中进行 grep,包括文件名):find . -type l -exec sh -c 'file -b "$1" | grep -q "^broken"' sh {} \; -print
find -L
引用的技巧独奏从命令行fu看起来又漂亮又老套,但它有一个非常危险的陷阱: 遵循所有符号链接。考虑包含以下内容的目录:
$ ls -l
total 0
lrwxrwxrwx 1 michal users 6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/
如果您find -L . -type l
在该目录中运行,/usr/share/
也会搜索所有内容(这可能需要很长时间)1。对于find
“不受传出链接影响”的命令,不要使用-L
。
1这可能看起来有点不便(该命令“只是”需要很长时间才能遍历所有/usr/share
)——但可能会产生更严重的后果。例如,考虑 chroot 环境:它们可以存在于主文件系统的某些子目录中,并包含指向绝对位置的符号链接。对于“外部”系统来说,这些链接似乎已被破坏,因为一旦您进入 chroot,它们只会指向正确的位置。我还记得一些引导加载程序使用的符号链接/boot
仅在初始引导阶段有意义,即引导分区安装为/
.
因此,如果您使用find -L
命令查找然后从一些看似无害的目录中删除损坏的符号链接,您甚至可能会破坏您的系统......
答案2
正如 rozcietrzewiacz 已经评论的那样,find -L
将搜索扩展到符号链接目录可能会产生意想不到的结果,因此这不是最佳方法。还没有人提到的是
find /path/to/search -xtype l
是更简洁、逻辑上相同的命令
find /path/to/search -type l -xtype l
到目前为止提出的解决方案都无法检测循环符号链接,这是另一种类型的破坏。 这个问题解决可移植性问题。总而言之,查找损坏的符号链接(包括循环链接)的可移植方法是:
find /path/to/search -type l -exec test ! -e {} \; -print
有关更多详细信息,请参阅这个问题或者ynform.org。当然,这一切的最终来源是findutils 文档。
答案3
命令symlinks
来自http://www.ibiblio.org/pub/Linux/utils/file/symlinks-1.4.tar.gz可用于识别具有各种特征的符号链接。例如:
$ rm a
$ ln -s a b
$ symlinks .
dangling: /tmp/b -> a
答案4
我相信将-L
标志添加到您的命令中将使您摆脱grep
:
$ find -L . -type l
http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks
从手册:
-L
使每个符号链接返回的文件信息和文件类型(参见
stat
(2))是链接引用的文件的信息和文件类型,而不是链接本身。如果引用的文件不存在,则文件信息和类型将用于链接本身。