Wednesday, July 16, 2008

A Twisty Maze of Symlinks, All Different: readlink -f

Which of the vi clones on your system are you using? Do you know?

In Linux, when more than one installed executable could reasonably have the same name a common solution is to make the executable in /bin or /usr/bin a symlink to an entry in /etc/alternatives.

The /etc/alternatives entry, in its turn, symlinks to the real executable. Or, maybe to another symlink to ...

Finding the ultimate executable in this twisty maze of symlinks, all different, can be an Adventure. The solution? readlink.

Here's an example, with java:
$ which java
/usr/bin/java
$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 2007-11-05 15:14 /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 36 2008-04-26 07:10 /etc/alternatives/java -> /usr/lib/jvm/java-6-sun/jre/bin/java
$ ls -l /usr/lib/jvm/java-6-sun/jre/bin/java
-rwxr-xr-x 1 root root 47116 2008-03-25 03:01 /usr/lib/jvm/java-6-sun/jre/bin/java
$ readlink -f /usr/bin/java
/usr/lib/jvm/java-6-sun-1.6.0.06/jre/bin/java
$ readlink -f $(which java)
/usr/lib/jvm/java-6-sun-1.6.0.06/jre/bin/java
Beware: readlink won't warn you if something's not a symlink (okay) or doesn't exist (not okay):
$ ls -l /home/jsh/java
ls: cannot access /home/jsh/java: No such file or directory
$ readlink -f /home/jsh/java
/home/jsh/java
$ echo $?
0

No comments: