Linux命令 –查找损坏的符号链接
1.概述
在本教程中,我们将看到如何使用不同形式的find命令来查找损坏的符号链接。
2.符号链接
符号链接、象征性链接,甚至是软链接是指向其他链接、文件、目录和资源的文件。它们类似于Windows中的快捷方式。
由于它们是链接,一旦目标不再可用,它们就会变得毫无用处。
我们的例子将在以下的目录结构中运行。
为了重现上述环境,我们可以在一个空的目录中运行这些命令。
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
3.寻找损坏的符号链接
find命令的结构如下。
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
-H、-L和-P选项控制了符号链接的处理方式,当省略时,使用-P作为默认。
当使用-P和find检查或打印来自符号链接的信息时,细节取自符号链接本身的属性。
我们将假设用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 -e。test是一个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. 。