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.)
-
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" fiDong Hoon : It doesn't seem to work on dangling links.From bdijkstra -
Either use
stat -Lor parse the output ofls -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!" fiTo normalise the path, use realpath:
fileone=`ls -1 s1 | sed 's/.*-> //'` fileone=`realpath $fileone` # etc...Dong Hoon : breaks on filenames containing "->"... thanks for the realpath tip though.Al : True... can't say I've ever had any files with -> in them. Readlink is definitely the way to go.From Al -
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.shyou can get the file name using
# ls -l msdfasdffff | awk -F"-> " '{print $NF}' blah.shthen 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
Dong Hoon : thx, but the awk-method breaks on filenames containing "->" as a substring; the find-method works, but a few conditions are lacking to restrict search to one file; i'd prefer the readlink command then.From ghostdog74 -
For GNU systems (and possibly others, but I can't say), there's
readlink(1):$ touch a $ ln -s a b $ readlink b aYou can use that in comparisons:
$ test $(readlink -f a) = $(readlink -f b) $ echo $? 0Al : +1 Ooh, I didn't know about that one!Dong Hoon : Thanks! This is what I was looking for.jleedev : @Torsten The stat (readlink) utility appeared in NetBSD 1.6.From Torsten Marek
0 comments:
Post a Comment