Portable way to get script's absolute path?

In zsh you can do the following:

mypath=${0:a}

Or, to get the directory in which the script resides:

mydir=${0:a:h}

Source: zshexpn(1) man page, section HISTORY EXPANSION, subsection Modifiers (or simply info -f zsh -n Modifiers).


With zsh, it's just:

mypath=$0:A

Now for other shells, though realpath() and readlink() are standard functions (the latter being a system call), realpath and readlink are not standard command, though some systems have one or the other or both with various behaviour and feature set.

As often, for portability, you may want to resort to perl:

abs_path() {
  perl -MCwd -le '
    for (@ARGV) {
      if ($p = Cwd::abs_path $_) {
        print $p;
      } else {
        warn "abs_path: $_: $!\n";
        $ret = 1;
      }
    }
    exit $ret' "$@"
}

That would behave more like GNU's readlink -f than realpath() (GNU readlink -e) in that it will not complain if the file doesn't exist as long as its dirname does.


I've been using this for several years now:

# The absolute, canonical ( no ".." ) path to this script
canonical=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)/$(basename -- "$0")")