How to find the original file of a soft link?

Command for following chains of links is named nameiManPage. Examples:

$ touch a
$ ln -s a b
$ ln -s b c
$ ln -s c d
$ namei ./d
f: ./d
 d .
 l d -> c
   l c -> b
     l b -> a
       - a
$ namei /usr/bin/java
f: /usr/bin/java
 d /
 d usr
 d bin
 l java -> /etc/alternatives/java
   d /
   d etc
   d alternatives
   l java -> /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
     d /
     d usr
     d lib
     d jvm
     d java-7-openjdk-i386
     d jre
     d bin
     - java

You can use the following shell function:

readmultilink () {
    linkfile="$1"
    if [ ! -L "$linkfile" ]; then 
        echo "$linkfile is not a simbolik link" >&2
        return 1
    fi
    until [ ! -L "$linkfile" ]; do
        lastlinkfile="$linkfile"
        linkfile=$(readlink "$lastlinkfile")
    done
    readlink "$lastlinkfile"
}

Add this function at the end of your ~/.bashrc file if you want to use it every time when you open the terminal.

Usage:

readmultilinks file_name

As example, for your example, readmultilinks d, readmultilinks c, and readmultilinks b will return a, but readmultilinks a will return a is not a simbolik link.


A simple solution:

readlink -f /path/to/file

You maybe need find instead:

$ find -L . -samefile d
./b
./c
./d
./a

Or:

$ ls -i d
143075 d
$ find . -follow -print -inum 143075
.
./b
./c
./d
./a

Both cases the original file is the last one.