两个文件是否被硬链接?


27

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

$ ls
fileA fileB fileC

$ is-hardlinked fileA fileB
yes

$ is-hardlinked fileA fileC
no

Answers:


37

在大多数文件系统¹上,文件是由其索引节点号唯一地确定的,因此您需要检查的是两个文件是否具有相同的索引节点号并且在同一文件系统上。

Ash,ksh,bash和zsh具有可为您进行检查的结构:文件相等运算符-ef

[ fileA -ef fileB ] && ! [ fileA -ef fileC ]

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

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


而且绝对不会在基于FAT的任何文件上被检测为“交叉链接”文件。
伊格纳西奥·巴斯克斯

4
请注意,如果是到的符号链接,反之亦然,或者它们都链接到同一文件,则fileA -ef fileB还返回0(成功)。fileAfileB
janmoesen 2011年

您实际上如何运行建议的命令?我试过了[.bashrc -ef .bash / .bashrc]及其变体,但实际上没有用。
查理·帕克

@CharlieParker [ .bashrc -ef .bash/.bashrc ]是正确的。当然,没有上下文,我也不知道为什么它“没有真正起作用”-您可能在比较错误的文件,可能无法正确检查结果,可能使用的外壳程序不带-ef... ...
Gilles 'SO-别再邪恶了'

2
@CharlieParker该命令实际上[是的同义词test。但是man [man test会给您提供外部命令的手册页,而几乎每个外壳程序都有一个内置的命令,带有稍微不同的选项,因此您需要在外壳程序手册中查找该命令。
吉尔斯(Gillles)“所以-别再邪恶了”

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

6
请注意,如果两个文件位于不同的文件系统上,但碰巧具有相同的inode,则这可能是误报。您还需要测试设备编号(stat -c %d)。而且,如果您使用的是Linux(根据stat命令),则您的Shell可以[ fileA -ef fileB ]直接执行所有这些操作。另外,您的命令无意间打乱了包含空格或的文件名\[?*,或者以-:开头:总是在命令符号"$(stat -c %i -- "$1")"前后加上双引号
吉尔(Gilles)'所以

1
为什么要使用一堆繁琐但可移植的结构,然后function使用功能名称(由于包含破折号)而违反了所允许名称的POSIX约定的,绝对不可移植的关键字?
查尔斯·达菲

您忘了引用$1$2。您可能还希望使用$()语法而不是反引号,因为方括号使该命令在何处开始,在何处结束以及嵌套更加简单。
josch

3

正如第一个发布者所建议的那样,您可以在Linux上基于以下内容编写脚本:

stat -c '%i' fileA fileB fileC

4
这还不够:如果两个文件位于不同的文件系统上,但恰好具有相同的inode,则两个文件的编号相同。您还需要测试设备编号(stat -c %d)。而且,如果您使用的是Linux(根据stat命令),则您的Shell可以[ fileA -ef fileB ]直接执行所有这些操作。
吉尔斯(Gilles)'所以

0

对于GNU find(1)4.2.11或更高版本,您还可以使用以下命令:

if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
    echo yes
else
    echo no
fi

如果fileA是与fileB然后相同的文件find将打印“是”,条件为真。

与使用文件相等运算符相比,-ef这将产生一个新进程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.