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.

Is there a *nix command to get absolute(and canonicalized) path from relative path(with current path) or symbolic link?

share|improve this question

4 Answers 4

up vote 31 down vote accepted

You can use the readlink utility, with the -f option:

-f, --canonicalize

      canonicalize  by  following  every symlink in every component of
      the given name recursively; all  but  the  last  component  must
      exist

Some distributions, for example those that use GNU coreutils and FreeBSD, also come with a realpath(1) utility that basically just calls realpath(3) and does pretty much the same thing.

share|improve this answer
6  
The -f switch does not exist on Mac OS X (at least as of 10.8.5). Without the -f switch it just returns an error code. –  iconoclast Sep 27 '13 at 2:43

Portably, the PWD variable is set by the shell to one absolute location of the current directory. Any component of that path may be a symbolic link.

case $f in
  /*) absolute=$f;;
  *) absolute=$PWD/$f;;
esac

If you want to eliminate . and .. as well, change to the directory containing the file and obtain $PWD there:

if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}

There's no portable way to follow symbolic links. If you have a path to a directory, then on most unices $(cd -- "$dir" && pwd -P 2>/dev/null | pwd) provides a path that doesn't use symbolic links, because shells that track symbolic links tend to implement pwd -P (“P” for “physical”).

Some unices provide a utility to print the “physical” path to a file.

  • Reasonably recent Linux systems (with GNU coreutils or BusyBox) have readlink -f, as do FreeBSD ≥8.3, NetBSD ≥4.0, and OpenBSD as far back as 2.2.
  • FreeBSD ≥4.3 has realpath (it's also present on some Linux systems, and it's in BusyBox).
  • If Perl is available, you can use the Cwd module.

    perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
    
share|improve this answer

Is pwd fit for your needs? It gives the absolute path of current directory. Or maybe what you want is realpath().

share|improve this answer

alister and rss67 in this article introduce most stable, compatible and easiest way. I never seen better way than this before.

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`

If you want to go back to the original location,

ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH

or

RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -

I wish this helps. This was greatest solution for me.

share|improve this answer
3  
That's actually not such a good way. Changing out of a directory and back in is not reliable: you might not have the permission to come back, or the directory might have been renamed in the meantime. Instead, change directories in a subshell: ABSPATH=$(cd -- "$RELPATH" && pwd). Note the double quotes around substitution (so as not to break if the path contains whitespace and globbing characters) and the -- (in case the path begins with -). Also this only works for directories, and doesn't canonicalize symbolic links as requested. See my answer for more details. –  Gilles Sep 27 '12 at 8:49

Your Answer

 
discard

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.