彻底查找通向文件/目录的所有链接(硬链接和符号链接及其任意组合)

彻底查找通向文件/目录的所有链接(硬链接和符号链接及其任意组合)

我想要,只使用“基本”命令(为了最大的可移植性)(即,可以在 AIX / Linux / 等上工作的东西,而不仅仅是使用最近的细节 ^^ 的东西)来查找全部指向特定文件/目录的文件(符号链接、硬链接及其组合)。

注意不要急于回答find / -ls | grep ....:这样会漏掉很多情况。请参阅下面的链接,混合硬链接、符号链接、相对路径和绝对路径(还可以使用符号链接“././././.”的可能性)

IE

  • 硬链接和符号链接可以“嵌套”,无限......
  • 一些符号链接可以是完整路径,其他符号链接可以是相对路径,
  • 这些路径(相对或绝对)可能非常复杂(例如: /tmp/./././etc/file )
  • 符号链接可能会导致一个文件,该文件硬链接到另一个文件,该文件又是到第三个文件的符号链接,最终[经过更多迭代]到达最终目的地......

最后,我“只是”需要找到一种方法来了解任何文件/链接的“最终目的地”是什么(即最终会访问哪个inode?)。但它是真的很难(除非一些神奇的功能会告诉我“最终目标索引节点是:...”。这就是我需要的!)

我以为我可以简单地使用 find 的“-H”或“-L”选项,但是(我可能很愚蠢......)它还没有起作用。

欢迎任何信息(但是请使用 find/ls/etc,而不是一些“仅在 linux 上可用的好实用程序”)

尝试创建一些指向“/tmp/A”目录的不同链接,并找到一种方法来查找并列出所有链接:

mkdir /tmp/A    /tmp/B
ln -s /tmp/A/   /tmp/B/D  #absolute symlink, with a training "/"
ln -s ../A      /tmp/B/E     #relative symlink
ln -s /tmp/A/.  /home/F  #absolute symlink, with a trailing "/."
ln -s ../tmp/A/./.  /var/L  #let's get craaaaaaazy! symlinks are "fun"...
ln    /tmp/B/D  /etc/G    #Hard-link to the symlink file /tmp/B/D, which itself symlink to /tmp/A/ witch ends up being the same as "/tmp/A" in most cases.
ln    /etc/G    /etc/G2   #and a duplicate of the previous one, just to be sure [so /etc/G, /etc/G2, and /tmp/B/D have same inode, but it's a different inode from the final destination... :(
ln -s etc/G /thatsenough   #symlink again, for further chaining

然后进行一些尝试:

find -H / -ls   # show inodes of the links and symlinks, not of the "final" directory
find -L / -ls   # same thing (I do try that on an OLD AIX ...)
find -H / -inum 123456 -ls  #if /tmp/A/. has inode 123456. This lists *only* hardlinks to /tmp/A, ie will only print a subset (and /tmp/A have to be a file in that case)

我希望在其中一个调用中看到所有路径前面的最终索引节点(123456)(我还在两者中添加了“-follow”),但我总是看到链接的索引节点,而不是“最终目的地”的索引节点“(即/tmp/A)

我可以用什么来找出我最终访问的“最终索引节点”? [操作系统管理它,但是一个“简单”命令可以预先告诉我“通过文件,您将打开最后的索引节点!”?]

答案1

这个问题没有统一的答案。例如,通过在树中链接几个符号链接,我可以创建无限多个解析到同一索引节点的可能路径。

您对完全可移植性的渴望也不太可能成功。例如,即使是“find”在 GNU、BSD、POSIX 和其他变体之间(当然还有这些变体的版本之间)也存在很大差异。

但你想要的可能类似于find / -samefile /absolute/path/to/file.

这在 GNU find >= 4.2.11 中可用。

答案2

ls有一个-L选项可以有效地追踪符号链接并显示最终对象的权限、所有者、索引节点等。 [它通过 dostat(target)而不是lstat(target)] 来做到这一点。为了获得最佳结果,请以 root 身份或对相关已安装文件系统具有读取权限的人员身份运行。

因此,对于您的情况,请尝试以下操作:

find / -exec ls -iLd {} | grep inodenum

[根据OP的要求,从我的评论中复制。]

答案3

更新:Mark Plottnick 的答案(在我的问题下)要简单得多,适用于文件和目录,并给出了最终目的地的索引节点,遵循其间链接的任意组合!
这就是我正在寻找的[除非我忘记了测试目录中的特殊情况]。
我很高兴最终的解决方案是如此优雅和便携!马克,请发布,以便我给您打勾^^

我在下面给出了自己的解决方法,现在看起来非常傻了^^

===

当目标文件是目录时,我发现了一些非常简单的解决方法!只需添加一个“/”即可。在其名称之后,您将获得最终目标的目录 inode!而且您仍然会打印原始路径!

find / -print | xargs -n 1 ls -ild '{}'/. 2>/dev/null | grep inodeyouwant

注意:“尝试在一个文件上执行此操作而不知道它是符号链接还是硬链接”中的内容非常繁重,因此我将更新为仅查找硬链接+符号链接的文件。

但现在我需要找到一种方法来为“最终不引导到目录”文件(即最终的链接/符号链接/链)执行此操作指向不是目录的东西)(再一次,不修改最终目的地!)

当我找到一个好的方法时我会更新

答案4

使用 GNU find

find -L . \( ! -xtype l -o -prune \) -samefile /path/to/the/file -print

将报告导致相同文件的不同规范路径/path/to/the/file

zsh

printf '%s\n' **/*(De:'[[ $REPLY -ef /path/to/the/file ]]')

还不[ file -ef other-file ]是 POSIX,但已得到广泛支持,并且有谈论将其包含在下一版本的规范中

find . -exec sh -c '
  for file do
    [ "$file" -ef /path/to/the/file ] && printf "%s\n" "$file"
  done' sh {} +

只要sh基于 AT&T kshpdkshbashzshashyash至少就应该可以工作(我不知道有任何 POSIXsh实现不基于这些实现)。

相关内容