Linux命令 –查找损坏的符号链接

评论 0 浏览 0 2019-10-17

1.概述

在本教程中,我们将看到如何使用不同形式的find命令来查找损坏的符号链接。

符号链接、象征性链接,甚至是软链接是指向其他链接、文件、目录和资源的文件。它们类似于Windows中的快捷方式。

由于它们是链接,一旦目标不再可用,它们就会变得毫无用处。

我们的例子将在以下的目录结构中运行。

baeldung linux commands find broken symlinks test environment

为了重现上述环境,我们可以在一个空的目录中运行这些命令。

mkdir -p baeldung/dir-1/dir-2/dir-3/
touch baeldung/file.txt
touch baeldung/dir-1/file-1.txt
touch baeldung/dir-1/dir-2/file-2.txt
touch baeldung/dir-1/dir-2/dir-3/file-3.txt
ln -s dir-2/dir-3/ baeldung/dir-1/dir-3
ln -s ../../file-1.txt baeldung/dir-1/dir-2/dir-3/file-1.txt
ln -s baeldung/nonexistent-directory baeldung/dir-1/dir-2/link-to-nonexistent-directory
ln -s dir-4/file-4.txt baeldung/dir-1/dir-2/dir-3/file-4.txt
ln -s dir-2/file-2.txt baeldung/dir-1/file-2.txt
ln -s ../filex.txt baeldung/dir-1/filex.txt
ln -s ../cyclic-link baeldung/dir-1/cyclic-link
ln -s dir-1/cyclic-link baeldung/cyclic-link
ln -s . baeldung/infinite-loop

find命令的结构如下。

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

-H-L-P选项控制了符号链接的处理方式,当省略时,使用-P作为默认

当使用-Pfind检查或打印来自符号链接的信息时,细节取自符号链接本身的属性。

我们将假设用Bash shell来执行我们的命令。

3.1.简单的方法

检测损坏的符号链接的最简单方法是使用下面的命令。

find baeldung -xtype l

在我们的环境中执行上述命令,将产生以下输出。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

在前两行中,我们可以看到,不仅我们’检测出损坏的符号链接,而且还报告了循环链接。在循环链接之后,我们看到了损坏链接。

我们使用了-xtype l 参数,它是true,只适用于损坏的符号链接

我们可以通过包括-P 标志来达到同样的目的。

find baeldung -P -xtype l

正如我们可能猜到的那样,这意味着-P是默认的

3.2.可移植的方法

对于符合POSIX标准的shell,我们可以使用下面的解决方案,因为-xtype可能不是在所有的系统上都可用

find baeldung -type l ! -exec test -e {} \; -print

正如预期的那样,输出结果将与上一次的样本相同。

baeldung/cyclic-link
baeldung/dir-1/cyclic-link
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

让我们把这里发生的事情分成几部分来讨论。

  • find命令正在寻找链接类型的文件,与我们在上一个样本中所做的相同
  • !是否定–exec表达式的结果,该表达式正在测试文件是否存在–否定该表达式将只显示不存在的文件。
  • exec表达式动作被用来对每个找到的文件执行命令。在这种情况下,我们要为每个文件执行test -etest是一个Linux命令,用于检查文件类型和比较数值。使用-e参数,我们正在检查文件是否存在
  • {}将被当前的文件名所取代。
  • \用于保护命令不被shell扩展––命令可以加引号,以避免使用“\“。
  • ;代表命令的结束。
  • -print将结果打印到标准输出端。

3.3.可移植和深入的方式

或者说,我们可以在许多网站上找到这种标准的解决方案。

find -L baeldung -type l

事实上,它甚至比上面的其他解决方案更好。这是因为它也报告了“文件系统循环”,我们可以在第二行看到。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: File system loop detected; ‘baeldung/infinite-loop’ is part of the same file system loop as ‘baeldung’
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
baeldung/dir-1/dir-3/file-4.txt
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

许多人不知道的副作用是,如果一个链接指向一个目录,这种方法就会进行深入的搜索。

例如,设想我们有一个指向/usr/share的链接。使用-L选项将使find遍历整个/usr/share结构。

这种方法可能需要太多的时间和资源来完成。在大多数情况下,这并不是我们想要做的事情。必须知道何时使用每种方法,并牢记其好处和后果。

因此,如果我们想在有指向目录的链接时,搜索目录内的损坏链接,我们可以使用-L选项

但是,如果我们想呆在我们特定的目录结构内,并且不想跟踪链接,我们就不需要使用-L

为了看到这种差异,我们可以启用调试功能,以显示所访问的每个文件和文件夹。

find -D search baeldung -xtype l
find -D search -L baeldung -type l

3.4.笨拙的方式

我们可以使用一种不同的方法,即使用用户权限级别来读取文件。

这有点像黑客,因为我们会看到损坏的链接,以及我们没有权限阅读的文件。换句话说,这个选项只真正适用于root用户。

也就是说,我们可以使用下面的命令来查找损坏的链接

find baeldung -type l ! -readable

这将产生一个类似于上一个样本的输出。

baeldung/cyclic-link
baeldung/dir-1/cyclic-link
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

在这种情况下,我们使用-type l,寻找类型为符号链接的文件。

然后我们用!来否定-readable参数。这将显示我们无法读取的文件。

由于我们无法读取损坏的链接,因此这些链接将作为结果的一部分被返回。

3.5.限制范围和深度

我们可以使用一些有用的测试表达式来限制我们的搜索范围。

  • lname模式。我们可以提供链接名称模式
  • ilname pattern。与lname相同,但不区分大小写
  • maxdepth: 搜索到该目录深度为止
  • mindepth: 从这个目录的深度搜索

作为一个例子,我们可以执行。

find baeldung -mindepth 3 -ilname "*.TXT" -xtype l

这将会产生输出。

baeldung/dir-1/dir-2/dir-3/file-4.txt

3.6.定制输出

我们可以自定义输出以提供更有用的信息。

通过表达式动作-ls,,我们可以得到关于链接的详细信息,以及它所指向的地方。

find baeldung -xtype l -ls

而输出的结果将是。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
 21109100      0 lrwxrwxrwx   1  fabio    fabio          12 Sep 17 23:26 baeldung/dir-1/filex.txt -> ../filex.txt
 21109086      0 lrwxrwxrwx   1  fabio    fabio          30 Sep 17 23:21 baeldung/dir-1/dir-2/link-to-nonexistent-directory -> baeldung/nonexistent-directory
 21109087      0 lrwxrwxrwx   1  fabio    fabio          16 Sep 17 23:21 baeldung/dir-1/dir-2/dir-3/file-4.txt -> dir-4/file-4.txt

文件名不常见时,这种方法并不奏效,因为它们可以包含除\0/以外的任何字符,甚至是换行符。

文件名中的不寻常的字符可以对我们的终端做意想不到的事情,而且往往是不可取的。例如,某些字符可以改变我们在某些终端上的功能键的设置。

4.总结

在这篇快速文章中,我们看到了如何使用简单的和更复杂的方法来寻找损坏的链接,如何限制搜索的范围,以及自定义输出。

find 工具是一把真正的瑞士军刀! 要了解更多,请看 find man page.

最后更新2022-12-04
0 个评论
标签