F4240
F4240

Reputation: 148

Compare a symlink and his target with bash test -ef

TL;DR: why [ symlink_to_file_a -ef file_a ] return true ?


I need to test if a file b (mostly symlink) is the same than a file a for trying to know if a and b are hard linked together, and hard link them if itsn't the case.
I use conditional expression -ef and bash manual says :

file1 -ef file2
True if file1 and file2 refer to the same device and inode numbers.

I compare just symlink/regular file and inodes of a and b are different but the result is True.

An answer of a similar question says :

If yes, then will the inode number be same for target and links?

No. Usually, the symlink is a file with its own inode, (with file-type, own data blocks, etc.)

I'm not sure of what I understood but I may found some explanations about it in ext4 spec :

The target of a symbolic link will be stored in this field if the target string is less than 60 bytes long. Otherwise, either extents or block maps will be used to allocate data blocks to store the link target.

I tried with target shorter/longer than 60B but there is no difference.

$ 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

Inodes are different but the test succeed and I didn't see what is wrong.

Upvotes: 1

Views: 1887

Answers (1)

Ruud Helderman
Ruud Helderman

Reputation: 11018

Seems like documentation is misleading in some places. From http://www.tldp.org/LDP/abs/html/fto.html:

f1 -ef f2

files f1 and f2 are hard links to the same file

As you already found out yourself, that expression returns true not only for hard links but also for soft links to the same file.

Use stat instead:

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

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

Upvotes: 2

Related Questions