Skip to content

Instantly share code, notes, and snippets.

@pendashteh
Last active April 10, 2018 02:08
Show Gist options
  • Save pendashteh/d0373d0275b8195982d08fbcb4010e94 to your computer and use it in GitHub Desktop.
Save pendashteh/d0373d0275b8195982d08fbcb4010e94 to your computer and use it in GitHub Desktop.
The realpath of the executed script

Here are different ways to obtain the realpath of the script. Each have their cons and pros and might have slight differences.

I am listing them here so overtime I can complete the list of cons and pros and what they actually do.

1.

script_root=$(dirname $(readlink -f $0))

2.

# Copyright http://stackoverflow.com/a/7400673/257479
myreadlink() { [ ! -h "$1" ] && echo "$1" || (local link="$(expr "$(command ls -ld -- "$1")" : '.*-> \(.*\)$')"; cd $(dirname $1); myreadlink "$link" | sed "s|^\([^/].*\)\$|$(dirname $1)/\1|"); }
whereis() { echo $1 | sed "s|^\([^/].*/.*\)|$(pwd)/\1|;s|^\([^/]*\)$|$(which -- $1)|;s|^$|$1|"; } 
whereis_realpath() { local SCRIPT_PATH=$(whereis $1); myreadlink ${SCRIPT_PATH} | sed "s|^\([^/].*\)\$|$(dirname ${SCRIPT_PATH})/\1|"; } 

script_root=$(dirname $(whereis_realpath "$0"))

3.

(not reliable)

# Copyright https://stackoverflow.com/a/13222994/257479
script_root=$(ls -l /proc/$$/fd | grep "255 ->" | sed -e 's/^.\+-> //')

Update: I found an example where this snippet failed. Haven't investigated what the problem was yet.

@alecthegeek
Copy link

alecthegeek commented Apr 9, 2018

I use

script_root=$(cd $(dirname "$0") || (echo cannot access $(dirname "$0"); exit -1); pwd)

It's low tech, but will probably work anywhere where there is a decent POSIX style shell, e.g. Linux Subsystem for Windows, although I have not tested that assumption

YMMV

@pendashteh
Copy link
Author

Using "$0" without readlink -f would not allow to execute another script using relative path, if the script is called via a symlink.

For example, here I am using script_root to source another bash script that contains functions that I need:
. $script_root/inc/helpers.sh

This will break with $(dirname "0") if the script is called as a symlink.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment