![为什么 bash 完成符号链接与目录不同?](https://linux22.com/image/2154/%E4%B8%BA%E4%BB%80%E4%B9%88%20bash%20%E5%AE%8C%E6%88%90%E7%AC%A6%E5%8F%B7%E9%93%BE%E6%8E%A5%E4%B8%8E%E7%9B%AE%E5%BD%95%E4%B8%8D%E5%90%8C%EF%BC%9F.png)
在搜索源代码时,我通常使用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 $SYMLINK
,find
会看到一个不是目录的对象,因此它不会遍历它。如果您想将目录的符号链接视为该目录,请/
在末尾添加 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'