Monday, May 25, 2009

Bash script to find its own location

Question: How can a bash script determine it's own location ?

Lets explore this using the following example script.

The script "" resides under my "~/work/engine/"(i.e. /home/user1/work/engine/) directory.

$ ls -l ~/work/engine/
total 4
-rwxr-xr-x 1 user1 users 239 2009-05-25 22:15

Have a look on the script: (The main intention of the script to print the location of the script and create some three directories named log,tmp,conf under the directory where this script resides)

$ cat ~/work/engine/

echo "Value of \$0 is : $0"

echo "path to script : ${0%/*}"
apath=$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")
echo "absolutepath is : $apath"

dname=$(dirname $apath)
echo "directory name : $dname"

mkdir -p $dname/{log,tmp,conf}

We will try to execute this script from "/home/user1/work" directory.

$ pwd

$ cd work/

Execute the script:

$ engine/


Value of $0 is : engine/
path to script : engine
absolutepath is : /home/user1/work/engine/
directory name : /home/user1/work/engine

Lets confirm the creation of the directories.

$ ls -l engine/

total 16
drwxr-xr-x 2 user1 users 4096 2009-05-25 22:15 conf
drwxr-xr-x 2 user1 users 4096 2009-05-25 22:15 log
-rwxr-xr-x 1 user1 users 239 2009-05-25 22:15
drwxr-xr-x 2 user1 users 4096 2009-05-25 22:15 tmp


Toon said...

Most of my scripts contain this logic

cd `dirname $0`
#directory of script is now `pwd`

#do stuff

#go back to directory where we were started

kezesb said...

This should also work, even when $0 is empty:

ls -l /proc/self/exe | sed 's/.*> //'

Clayton said...

If you source your "" script from another script, you run into problems because $0 is set by the calling script.

Say you want the calling script to get the $apath and $dpath variables that sets. First you'd change by adding 'export ' in from of the lines that set the variables you want to export (aname and dpath). Then your calling script ( might like this:

# source to get the env variables it sets

# note the period and space in front - that's what makes it "source"
. bin/

echo "apath=$apath"
echo "dname=$dname"

### end

I'm struggling with this now to try to make sure a script of my own can always find itself, and so far I haven't been able to figure it out.
So far even the extremely powerful technique pointed out by kezesb hasn't worked; I think this is because of the nature of sourcing. I suspect a sourced script can never know where it is.

© Jadu Saikia