Reputation: 889
What would be an elegant way of comparing 2 symbolic links in Unix?
Assume I have entered the following commands:
ln -s /usr/share/g s1
ln -s /usr/share/g s2
ln -s ../share/g /usr/lib/s3
ln -s /usr/share/h s4
then I would like to have a command that says that s1 and s2 are equal (whether /usr/share/g actually exists is not relevant), that s1 and s4 are not equal, s2 and s4 are not equal. (For my purpose it suffices that s3 is reported to differ from s1 and s2; however if comparison after path normalization could be done, that may be useful to.)
Upvotes: 3
Views: 3247
Reputation: 86642
For GNU systems (and possibly others, but I can't say), there's readlink(1)
:
$ touch a
$ ln -s a b
$ readlink b
a
You can use that in comparisons:
$ test "$(readlink -f a)" = "$(readlink -f b)"
$ echo $?
0
Upvotes: 12
Reputation: 129
Wrong:
test $(readlink -f a) = $(readlink -f b)
because a
or b
may point to names with spaces, and in this case test
will see more than 3 arguments.
Right:
cmp -s <(readlink -- a) <(readlink -- b)
echo $?
If you need to check recursively, say readlink -f
instead of readlink
. The double dashes --
inside the parens are needed only if a
or b
are variables, such as $1
, $2
, $var
…. The switch -s
is needed only if you need the result of the comparison for further processing rather than the printout of cmp
. If you do wish to have a printout, better say
diff <(readlink -- a) <(readlink -- b)
echo $?
Upvotes: 0
Reputation: 72736
Either use stat -L
or parse the output of ls -l
(with sed or cut or similar):
fileone=`ls -l s1 | sed 's/.*-> //'`
filetwo=`ls -l s2 | sed 's/.*-> //'`
if [ "$fileone" = "$filetwo" ]
then
echo "They're the same!"
fi
To normalise the path, use realpath:
fileone=`ls -1 s1 | sed 's/.*-> //'`
fileone=`realpath $fileone`
# etc...
Upvotes: 0
Reputation: 289
You could do a stat -L on the file and compare device and inode number. Quick example:
#!/bin/bash
DI_A=$(stat -c "%d.%i" -L "$1")
DI_B=$(stat -c "%d.%i" -L "$2")
if [ "$DI_A" == "$DI_B" ]; then
echo "same file"
else
echo "other file"
fi
Upvotes: 4
Reputation: 343137
2 ways i can think of, you can use ls -l on both files. you can see after the "->" of the output the actual path.eg
# ls -ltr msdfasdffff
lrwxrwxrwx 1 root root 10 Jun 30 19:05 msdfasdffff -> blah.sh
you can get the file name using
# ls -l msdfasdffff | awk -F"-> " '{print $NF}'
blah.sh
then you can compare with another link.
the other way is use find
# var1=$(find . -name "s1" -printf "%l")
# var2=$(find . -name "s2" -printf "%l")
then you can compare the 2 variables using if/else
Upvotes: -1