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 "mypath.sh" 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 mypath.sh


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


$ cat ~/work/engine/mypath.sh
#!/bin/sh

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
/home/user1

$ cd work/


Execute the script:

$ engine/mypath.sh

output:

Value of $0 is : engine/mypath.sh
path to script : engine
absolutepath is : /home/user1/work/engine/mypath.sh
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 mypath.sh
drwxr-xr-x 2 user1 users 4096 2009-05-25 22:15 tmp

3 comments:

Toon said...

Most of my scripts contain this logic

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

#do stuff
...

#go back to directory where we were started
cd $STARTDIR

kezesb said...

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

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

Clayton said...

If you source your "mypath.sh" 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 mypath.sh sets. First you'd change mypath.sh by adding 'export ' in from of the lines that set the variables you want to export (aname and dpath). Then your calling script (calling.sh) might like this:


#!/bin/bash
# calling.sh: source mypath.sh to get the env variables it sets

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

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

### end calling.sh

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 www.UNIXCL.com