为什么 Linux shell 命令 test -ef 不能像手册中描述的那样对软链接起作用?

问题描述 投票:0回答:1

我创建了一个指向

hard
student.sh
链接和一个指向
soft
student.sh
链接。
hard
链接与
soft
链接具有不同的 inode。 但是,当使用
soft
命令将
student.sh
test -ef
进行比较时,它无法按预期工作。 我已经检查了
ln
test
命令的手册,但仍然对它们感到困惑。

$ man test
$ man ln

FILE1 -ef FILE2
  FILE1 and FILE2 have the same device and inode numbers

$ ln /home/pi/Desktop/links/student.sh hard
$ ln -s /home/pi/Desktop/links/student.sh soft

$ ls -ial
278224 drwxr-xr-x  2 pi pi 4096  6月  5 23:31 .
262125 drwxr-xr-x 12 pi pi 4096  6月  5 23:17 ..
278227 -rwxr-xr-x  2 pi pi   43  6月  5 23:20 hard
278225 lrwxrwxrwx  1 pi pi   33  6月  5 23:31 soft -> /home/pi/Desktop/links/student.sh
278227 -rwxr-xr-x  2 pi pi   43  6月  5 23:20 student.sh

测试

# ❌ inode is different
$ [ ./student.sh -ef ./soft ] && echo yes || echo no
yes

$ [ ./student.sh -ef ./hard ] && echo yes || echo no
yes

更新测试用例

./test.sh

#!/usr/bin/env bash

if [[ ./student.sh -ef ./soft ]]; then
  echo "yes"
else
  echo "no"
fi

if [[ ./student.sh -ef ./hard ]]; then
  echo "yes"
else
  echo "no"
fi
$ ./test.sh 
yes
yes

想要

# inode is different, so it should output no ✅
$ [ ./student.sh -ef ./soft ] && echo yes || echo no
no

$ [ ./student.sh -ef ./hard ] && echo yes || echo no
yes

linux shell symlink hardlink ln
1个回答
1
投票

就像 Barmar 在评论中提到的那样,并且如

bash
关于条件表达式的手册部分中所述:

除非另有说明,否则对文件进行操作的主程序遵循符号链接并对链接的目标进行操作,而不是对链接本身进行操作。

您可以使用

stat(1)
来获取设备编号和 inode 而不用跟随符号链接,并比较这些值:

$ is_same_file () { test "$(stat -c "%d %i" "$1")" = "$(stat -c "%d %i" "$2")"; }


$ if is_same_file student.sh hard; then echo yes; else echo no; fi
yes
$ if is_same_file student.sh soft; then echo yes; else echo no; fi
no

PS:

is_same_file ()
等价于以下代码

# use the keyword `function`
function is_same_file () {
  # The return value is the exit status code
  # of the execution result of the last line of command.
  return test "$(stat -c "%d %i" "$1")" = "$(stat -c "%d %i" "$2")";
}

只要 GNU coreutils

bash
命令可用,这应该适用于任何 POSIXish shell,而不仅仅是
stat(1)
,这似乎是一个安全的选择,因为你正在谈论 Linux。如果使用其他环境可能需要调整;例如,NetBSD
stat(1)
使用
-f
而不是
-c
)。

© www.soinside.com 2019 - 2024. All rights reserved.