如何在 Linux 中有效跟踪硬链接?

sam*_*ers 7 find hard-link inode

软链接很容易追踪到原始文件readlink等......但我很难追踪到原始文件的硬链接。

$ ll -i /usr/bin/bash /bin/bash  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /usr/bin/bash*
                   ^
Run Code Online (Sandbox Code Playgroud)

上面是预期的 - 很酷 --> 两个文件都指向相同的 inode 1310813
(但由 指示的链接数^显示为 1。从 Gilles 的回答中可以理解其原因)

$ find / -samefile /bin/bash 2>/dev/null
/usr/bin/bash
Run Code Online (Sandbox Code Playgroud)

以上是预期的 - 所以没有问题。

$ find / -samefile /usr/bin/bash 2>/dev/null
/usr/bin/bash  
Run Code Online (Sandbox Code Playgroud)

上面酷。如何使用文件作为参考跟踪原始文件或每个硬链接/usr/bin/bash

奇怪 - 下面也没有帮助。

$ find / -inum 1310813 2>/dev/null
/usr/bin/bash
Run Code Online (Sandbox Code Playgroud)

Ste*_*itt 45

第一,硬链接的情况下没有原始文件;所有硬链接都是平等的。

但是,此处不涉及硬链接,如ls -l输出中的链接数 1 所示:

$ ll -i /usr/bin/bash /bin/bash  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /usr/bin/bash*
Run Code Online (Sandbox Code Playgroud)

您的问题是由符号链接引起的,bin符号链接指向usr/bin. 要查找可用的所有路径bash,您需要find使用以下-L选项告诉遵循符号链接:

$ find -L / -xdev -samefile /usr/bin/bash 2>/dev/null
/usr/bin/rbash
/usr/bin/bash
/bin/rbash
/bin/bash
Run Code Online (Sandbox Code Playgroud)

我在-xdev这里使用是因为我知道您的系统安装在单个文件系统上;这避免了降入/dev/proc/run/sys等。

  • 这里没有额外的硬链接。 (3认同)
  • 据我所知,我的回答并没有说这是一个硬链接。OP 正在寻找安装给定二进制文件的路径(有关上下文,请参阅 [this question](https://unix.stackexchange.com/q/607504/86440));由于`/usr` 合并,`bash` 安装为`/bin/bash`,但也显示为`/usr/bin/bash`。 (3认同)
  • 值得指出的是,您可以看出没有硬链接,因为链接数为“1”。这就是你如何知道它一定是别的东西。 (2认同)

Gil*_*il' 24

如何使用 /usr/bin/bash 文件作为参考来跟踪原始文件或每个硬链接

使用 GNU find(或find具有该-samefile选项的任何其他版本),并假设它/usr/bin/bash位于/文件系统上,这是正确的:

find / -xdev -samefile /bin/bash
Run Code Online (Sandbox Code Playgroud)

使用,-xdev因为硬链接不能跨越文件系统边界。不要重定向错误:如果您没有遍历目录的权限,则该目录下可能存在硬链接而您会错过它。

您犯的错误是您正在寻找另一个不存在的硬链接。你实际上有信息知道它不存在:

1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*
                   ^
Run Code Online (Sandbox Code Playgroud)

的硬链接数/bin/bash为 1。

有一个//usr/bin/bash. 该文件/bin/bash相同的/usr/bin/bash原因不同:目录 /bin/usr/bin是同一个文件。由于find / -samefile /bin/bash指向/usr/bin/bash/bin具有到 的符号链接/usr/bin。更准确地说,根据问题中的信息,并假设这/bin不是目录硬链接(支持不佳、很少使用的功能),我们知道这/bin是一个符号链接,解析为/usr/bin; 它可能是到另一个符号链接的符号链接,依此类推,最终解析为/usr/bin或到某个等效路径,例如///////usr/bin/,但很可能它是一个符号链接,其目标是/usr/bin.

在整个系统上查找文件的所有符号链接并不是特别有效。例如,在 Linux 上,有一个文件/proc/*/exe是每个运行 bash 的进程的/usr/bin/bash(或/bin/bash)符号链接。如果您查找指向目录的符号链接,您最终会陷入无限递归,例如/proc/*/root指向/(chrooted 进程除外)。

如果需要知道两个路径是否指向同一个文件,在Linux上,可以使用

[ /bin/bash -ef /usr/bin/bash ]
test /bin/bash -ef /usr/bin/bash
Run Code Online (Sandbox Code Playgroud)

-ef不是 POSIX,但它在 dash、bash、BusyBox 和 GNU coreutils 中)。如果您需要获取文件的规范路径,即不同的文件总是具有不同的规范名称,您可以使用

readlink -f /bin/bash
Run Code Online (Sandbox Code Playgroud)

(这可能会错过通过挂载目录相同的文件,例如,如果以两种不同的方式挂载相同的网络位置。)