我想要,只使用“基本”命令(为了最大的可移植性)(即,可以在 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 ksh
、pdksh
、bash
、zsh
、ash
或yash
至少就应该可以工作(我不知道有任何 POSIXsh
实现不基于这些实现)。