I create a hard
link to student.sh
and a soft
link to student.sh
.
The hard
links have different inodes than soft
links.
But when comparing the soft
with student.sh
by using the test -ef
command, it does not work as expected.
I had checked the manuals of the ln
and test
commands but still confused with them.
$ man test
# 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
update test case
./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
Like Barmar mentioned in a comment, and as documented in the bash
manual section on conditional expressions:
Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself.
You can use stat(1)
to get the device number and inode without following symbolic links, and compare those values, though:
$ 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
This should work on any POSIXish shell, not just bash
, as long as the GNU coreutils stat(1)
command is available, which seems a safe bet since you're talking about Linux. Might need to be adjusted if using some other enviroment; the NetBSD stat(1)
, for example, uses -f
instead of -c
).