将符号链接及其目标与 bash test -ef 进行比较

Posted

技术标签:

【中文标题】将符号链接及其目标与 bash test -ef 进行比较【英文标题】:Compare a symlink and his target with bash test -ef 【发布时间】:2017-04-10 08:13:18 【问题描述】:

TL;DR:为什么 [ symlink_to_file_a -ef file_a ] 返回 true ?


我需要测试文件 b(主要是符号链接)是否与文件 a 相同,以尝试了解 ab 是硬链接在一起的,如果不是这样,则硬链接它们。 我使用条件表达式-ef 和bash manual 说:

文件1 -ef 文件2 如果 file1 和 file2 引用相同的设备和 inode 号,则为真。

我只比较符号链接/常规文件,ab 的 inode 不同,但结果是 True

类似question 的回答说:

如果是,那么目标和链接的 inode 编号是否相同?

没有。通常,符号链接是一个有自己的 inode 的文件,(有文件类型、自己的数据块等)

我不确定我理解了什么,但我可能会在 ext4 spec 中找到一些解释:

如果目标字符串的长度小于 60 字节,则符号链接的目标将存储在此字段中。否则,将使用extents或block maps来分配数据块来存储链接目标。

我尝试使用比 60B 更短/更长的目标,但没有区别。

$ cat test.sh
#!/usr/bin/env bash
foo="foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
mkdir /tmp/test
cd /tmp/test
touch a
ln -s /tmp/test/a b
ls -li
if [ a -ef b ]
then
  echo b : same device or inode of a
 else
  echo b : different device or inode of a
fi
mkdir /tmp/test/$foo
cd /tmp/test/$foo
touch c
ln -s /tmp/test/$foo/c d
ls -li
if [ c -ef d ]
then
  echo d : same device or inode of c
else
  echo d : different device or inode of c
fi
$ ./test.sh
156490 -rw-rw-r-- 1 msi msi  0 nov.  25 23:55 a                                                                                                                                                                                                
156491 lrwxrwxrwx 1 msi msi 11 nov.  25 23:55 b -> /tmp/test/a                                                                                                                                                                                 
b : same device or inode of a                                                                                                                                                                                                                  
total 4                                                                                                                                                                                                                                        
156494 -rw-rw-r-- 1 msi msi   0 nov.  25 23:55 c
156495 lrwxrwxrwx 1 msi msi 155 nov.  25 23:55 d -> /tmp/test/foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/c
d : same device or inode of c

inode 不同,但测试成功,我没有发现问题所在。

【问题讨论】:

请注意,在您链接到的手册部分的顶部附近,它说: 除非另有说明,否则对文件进行操作的主文件遵循符号链接并在链接的目标上进行操作,而不是链接本身。。也就是说,除了在检查某个东西是否是符号链接(大致)时,它使用stat() 系统调用而不是lstat() 系统调用。 ext4 信息只是关于符号链接指向的路径的磁盘存储;它不会影响功能(但会略微影响性能,因为必须为非常长的符号链接读取额外的磁盘块)。 我认为具体的说明会很详尽:/ 感谢您的完整解释。 【参考方案1】:

似乎文档在某些地方具有误导性。来自http://www.tldp.org/LDP/abs/html/fto.html:

f1 -ef f2

文件 f1f2 是指向同一个文件的硬链接

正如您已经发现的那样,该表达式不仅对硬链接返回 true,而且对指向同一文件的 链接返回 true。

改用stat

if [ "$(stat -c "%d:%i" FILE1)" == "$(stat -c "%d:%i" FILE2)" ]

来源: https://superuser.com/questions/196572/check-if-two-paths-are-pointing-to-the-same-file

【讨论】:

以上是关于将符号链接及其目标与 bash test -ef 进行比较的主要内容,如果未能解决你的问题,请参考以下文章

删除目录中的所有文件而不删除符号链接及其指向的文件

如何获取符号链接的目标?

浅谈软硬链接

GCC中的弱符号与强符号

《程序员自我修养》阅读笔记-静态链接

深入理解计算机系统链接