两个文件是硬链接的吗?

Vin*_*eib 32 shell files

如何从命令行判断两个文件是否硬链接?例如一些链接:

$ ls
fileA fileB fileC

$ is-hardlinked fileA fileB
yes

$ is-hardlinked fileA fileC
no
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 43

在大多数文件系统¹上,文件由其inode编号唯一确定,因此您需要检查的只是这两个文件是否具有相同的 inode 编号并位于同一文件系统上。

Ash、ksh、bash 和 zsh 有一个结构可以为您进行检查:文件相等运算符-ef

[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
Run Code Online (Sandbox Code Playgroud)

对于更高级的情况,ls -i /path/to/file列出文件的 inode 编号。df -P /path/to/file显示文件所在的文件系统(如果两个文件在同一目录中,则它们在同一文件系统上)。如果您的系统有该stat命令,它可能会显示 inode 和文件系统编号(stat因系统而异,请查看您的文档)。如果您想快速浏览目录中的硬链接,请尝试ls -i | sort(可能通过管道传输到 awk)。

¹ 所有原生 unix 文件系统,以及一些其他文件系统,例如 NTFS,但可能不是 CramFS 等特殊情况。

  • 请注意,如果“fileA”是指向“fileB”的符号链接(反之亦然),或者它们都链接到同一个文件,则“fileA -ef fileB”也会返回“0”(成功)。 (7认同)
  • @CharlieParker 命令实际上是`[`,是`test` 的同义词。但是`man [` 或`man test` 会给你提供外部命令的手册页,而几乎每个shell 都有一个带有稍微不同选项的内置命令,所以你需要在你的shell 中查找这个手动的。 (3认同)

小智 5

function is-hardlinked() {
    r=yes
    [ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
    echo $r
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果两个文件位于不同的文件系统但碰巧具有相同的 inode,则这可能是误报。您还需要测试设备编号(`stat -c %d`)。如果你在 Linux 上(给定你的 `stat` 命令),你的 shell 有 `[ fileA -ef fileB ]` 来直接完成所有这些。此外,您的命令会以包含空格或 `\[?*` 的文件名无缘无故地中断,或者以 `-` 开头:**总是在命令 susbtitutions 周围加上双引号 ** (`"$(stat -c %i -- " $1")"`)。 (8认同)
  • 为什么要使用一堆繁琐但可移植的结构,然后使用带有函数名称(由于包含破折号)的函数名称(由于包含破折号)违反 POSIX 对允许名称的约定的非常不可移植的 `function` 关键字? (3认同)