Bash equivalent for PHP realpath()

For all you PHP hackers trying to write a BASH script and looking for an equivalent for PHP’s realpath function, try readlink. It can expand symbolic links and resolve relative paths like “./” and “../”. In a shell script, try this:

MY_PATH=$(readlink -f $0)

Thanks to Barry.

Published by

Andy Skelton

Code Wrangler Automattic

11 thoughts on “Bash equivalent for PHP realpath()”

  1. If you put quotation marks around the variable expansion you’ll be able to gracefully handle paths with spaces in them as well:

    MY_PATH=$(readlink -f “$0”)

  2. saddly, readlink on Mac OS X has almost a completely different implementation and this particular method doesn’t work. sigh. still looking around….

  3. me again, or:
    # This function expands ~ in pathname and
    # resolves the given path using perl or python or php realpath
    function resolvepath () {
    if [[ “${1}” == \~*/* || “${1}” == \~ || “${1}” == \~/* || “${1}” == \~/ ]]; then

    PYTHON_CMD=$(which python)
    PERL_CMD=$(which perl)
    PHP_CMD=$(which php)

    if [ ! -z “${PYTHON_CMD}” ]; then
    resolved_path=$(“${PYTHON_CMD}” -c ‘import os;print os.path.realpath(“‘”$p”‘”);’)
    elif [ ! -z “${PERL_CMD}” ]; then
    resolved_path=$(“${PERL_CMD}” -e ‘use Cwd qw(realpath);print realpath(“‘”$p”‘”);’)
    elif [ ! -z “${PHP_CMD}” ]; then
    resolved_path=$(“${PHP_CMD}” -r “echo realpath(‘$p’);”)
    fi #linux readlink -f

  4. I’m afflicted with the darwin version of readlink. For one script I needed to be able to resolve paths of directories only, and the following solution did it for me.

    cd “$1” 2>/dev/null || return $? # cd to desired directory; if fail, quell any error messages but return exit status
    echo “`pwd -P`” # output full, link-resolved path

    # sample usage
    if abs_path=”`dir_resolve \”$1\”`”
    echo “$1 resolves to $abs_path”
    echo pwd: `pwd` # function forks subshell, so working directory outside function is not affected
    echo “Could not reach $1”

  5. If you simply need to return the full path of the running script and you CAN use readlink… this one-liner should work well as long as its defined at the top of the script before the inital PWD changes.

    MY_PATH=$(readlink -f $(type -a $0 |awk ‘{print $3}’))

  6. For general use, it’s probably safer to use $(readlink -m $path) for this purpose. With the -f switch the file must exist, but with -m it doesn’t matter. It depends on your purposes, but it’s good to be aware of this in any case. If I convert a path using readlink -f and then check if it’s empty, I won’t know whether it’s empty because the original path was empty, or because the file doesn’t exist.

  7. The following Ruby script works well for me on Mac 10.7 and Ubuntu 12.04:

    #!/usr/bin/env ruby
    unless (1..2).include? ARGV.size
    STDERR.write(“usage: #{File.basename $0} filename [dirstring]\n”)
    exit 1
    puts File.expand_path( *ARGV )

Comments are closed.