为什么 bash 完成符号链接与目录不同?

为什么 bash 完成符号链接与目录不同?

在搜索源代码时,我通常使用find环境变量作为路径。最近我用符号链接替换了环境变量,它破坏了 Bash 的 shell 完成。当我find使用符号链接时,它不起作用,但如果我使用符号链接指向的实际路径,它就可以找到。

ln -s /some/source/dir /the/source
export SYMLINK=/the/source
export DIR=/some/source/dir

find $SYMLINK -name file.c        // doesn't find anything
find $DIR -name file.c            // works as expected

在此示例中,$SYMLINK 是 $DIR 值的符号链接。

那么,为什么 bash 以不同的方式处理符号链接环境变量呢?

答案1

这不是 bash,而是 find;尽管您会发现大多数实用程序都遵循相同的原则:

  • 如果对文件内容进行操作,则常规文件的符号链接相当于实际文件。
  • 如果对目录条目进行操作,则符号链接是其自己的类别。

当您运行 时find $SYMLINKfind会看到一个不是目录的对象,因此它不会遍历它。如果您想将目录的符号链接视为该目录,请/在末尾添加 a (一些损坏的系统或命令可能需要"$SYMLINK/."):

find "$SYMLINK/" -name file.c

对于find,您还可以使用该-H选项,该选项告诉它处理命令行上的任何符号链接,就像您指定了目标一样:

find -H "$SYMLINK" -name file.c

答案2

不是bash,是find。在递归目录遍历中遵循符号链接通常会导致无限循环(考虑ln -s foo .提供兼容性路径的常见技巧)。 POSIXfind包含-follow谓词来覆盖它;也许在这种情况下更有用,GNU find-H只跟踪直接指定为参数的符号链接,同时继续避免扩展遍历期间找到的符号链接。您可以将它们与别名一起使用:

alias find='find -H'

相关内容