Given an absolute or relative path (in a Unix-like system), I would like to determine the full path of the target after resolving any intermediate symlinks. Bonus points for also resolving ~username notation at the same time.

If the target is a directory, it might be possible to chdir() into the directory and then call getcwd(), but I really want to do this from a shell script rather than writing a C helper. Unfortunately, shells have a tendency to try to hide the existence of symlinks from the user (this is bash on OS X):

Note since GNU coreutils 8.15 (2012-01-06), there is a realpath program available that is less obtuse and more flexible than the above. It's also compatible with the FreeBSD util of the same name. It also includes functionality to generate a relative path between two files.

realpath - return the canonicalized absolute pathname
realpath expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the null terminated string named by path and
stores the canonicalized absolute pathname in the buffer of size PATH_MAX named by resolved_path. The resulting path will have no symbolic link, '/./' or
'/../' components.

On Debian (etch and later) this command is available in the realpath package.
–
Phil RossJun 25 '09 at 11:39

1

realpath is now (Jan 2012) part of coreutils and backwards compatible with the debian and BSD variant
–
pixelbeatApr 16 '12 at 7:43

1

I don't have realpath on Centos 6 with GNU coreutils 8.4.31. I've come across several others on Unix & Linux that have a GNU coreutils packaged withoutrealpath. So it seems to be dependent on more than just version.
–
toxalotMar 18 '14 at 22:43