Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

For use in a shell-script, I'm looking for a commandline-way to get the destination of a symbolic link. The closest I've come so far is stat -N src, which outputs src -> dst. Of course I could parse the output and get dst, but I wonder if there is some direct way of getting the destination.

share|improve this question

4 Answers 4

up vote 17 down vote accepted

Another option would be to use the specifically designed command readlink if available.

share|improve this answer
Use readlink -f if you want to know the last symlink target and not only the next one. –  scai Sep 10 '12 at 14:25
Good point! Forgot that. –  vitiv Sep 10 '12 at 14:27
Note that -f is a non-portable extension to GNU readlink. –  bahamat Sep 10 '12 at 21:38
When would readlink not be available? Thanks. –  tommy.carstensen Jul 29 at 12:55

This can be done using GNU find: find src -prune -printf "%l\n".

share|improve this answer

Portably: no luck except using heuristics to parse ls -l output, or use perl -le 'print readlink("some-file")'

some systems have a readlink command, some with a -f option to obtain the absolute path.

There are various implementations of a stat command as a wrapper for the stat/lstat system calls. The GNU one is not useful in that regard, but zsh's builtin one is more so:

zmodload zsh/stat
stat +link the-link

Still with zsh, you can get the absolute path of a file (removes every symlink component) with the :A modifier (applies to variable expansion, history expansion and globbing:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
~$ echo b(:A)
~$ echo ?(@:A)
share|improve this answer

On Mac OS X and FreeBSD/NetBSD/etc. it's:

stat -f %Y <filename>

More generically I guess the solution is (stat --printf=%N uses weird quotes):

ls -l b | sed -e 's/.* -> //'


# ln -s a b
# stat -f %Y b
# find b -maxdepth 0 -printf %l

The last line is mangled because it has no newline, but that is fine if you need the result in a variable, like so

# f=$(find b -maxdepth 0 -printf %l)
# echo $f

The -maxdepth is needed to prevent find from descending into directories if b happens to be a directory.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.