Bash Script: Find Out In What Directory Script Is Stored Under Unix Or Linux

by on December 11, 2012 · 7 comments· LAST UPDATED December 12, 2012

in , ,

How can I find out the path of the directory in which my bash shell script is located and store that path in _base variable?

You need to use the combination of the following:

[a] readlink - Display value of a symbolic link or canonical file name.

Tutorial details
DifficultyEasy (rss)
Root privilegesNo
RequirementsUnix like+
bash
Estimated completion timeN/A
This is a safe way to get the target of a symbolic link.

[b] ${BASH_SOURCE[0]} or $0 - The name of the shell script file is stored in $0 or ${BASH_SOURCE[0]}

Please note that the following examples are only tested on the Bash shell running on Debian Linux. This code may not be portable and may break on other Linux distributions/Unix like operating systems.

Examples

Create a shell script as follows:

#!/bin/bash
# Name: /tmp/demo.bash : 
# Purpose: Tell in what directory $0 is stored in
# Warning: Not tested for portability 
# ------------------------------------------------
 
## who am i? ##
_script="$(readlink -f ${BASH_SOURCE[0]})"
 
## Delete last component from $_script ##
_base="$(dirname $_script)"
 
## Okay, print it ##
echo "Script name : $_script"
echo "Current working dir : $PWD"
echo "Script location path (dir) : $_base"
 

Save and close the file. Run it as follows:
$ chmod +x /tmp/demo.bash
$ /tmp/demo.bash

Sample outputs:

Script name : /tmp/demo.bash
Current working dir : /home/vivek
Script location path (dir) : /tmp

cd to /home/vivek
$ cd ~
$ /tmp/demo.bash

Sample outputs:

Script name : /tmp/demo.bash
Current working dir : /home/vivek
Script location path (dir) : /tmp

Run it as follows:
$ ../../tmp/demo.bash
Sample outputs:

Script name : /tmp/demo.bash
Current working dir : /home/vivek
Script location path (dir) : /tmp

Finally, create a symbolic link in /home/vivek and test it:
$ cd ~
$ ln -s /tmp/demo.bash
$ ./demo.bash
$ rm demo.bash

Sample outputs:

Script name : /tmp/demo.bash
Current working dir : /home/vivek
Script location path (dir) : /tmp

Know a better way to solve this problem? Add in the comments below.

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 7 comments… read them below or add one }

1 Nikesh December 11, 2012 at 1:23 pm

# Dir in which bash script is
echo `pwd`

# name of bash script file
echo `$0

Reply

2 kustodian December 11, 2012 at 7:51 pm

echo `pwd` is not the directory in which the script is located in, but the current working directory, and echo $0 will not the print the name of the script, but the name of the command that is called. For example if the script is located in /home/username/my_script.sh and it contains:

echo `pwd`
echo $0

then if you run the following commands:

cd /tmp
/home/username/my_script.sh

the script will print:

/tmp
/home/username/my_script.sh

and we want to print the dir of the script (/home/username), and the name of the script (my_script.sh).

I would just like to confirm that readlink -f works for me on both Centos 5 and 6.

Reply

3 Andy December 11, 2012 at 1:41 pm

I tend to use

_base=$(cd $(dirname $0); pwd -P)

Reply

4 nixCraft December 11, 2012 at 1:53 pm

Nice one liner. But, it will fail with softlink (see the last example ln -s).

Reply

5 Shantanu Gadgil December 12, 2012 at 6:34 am

A couple of recommended optimizations (Linux only)
* use ‘readlink -m’ instead of ‘readlink -f’
* avoid using ‘dirname’, use bash’s internal ‘string cut’ functionality

Cheers,
Shantanu

Reply

6 kustodian December 12, 2012 at 11:47 pm

Why is ‘readlink -m’ better than -f?

What do you mean buy bash’s internal ‘string cut’? Do you mean this:

echo ${0##*/}

Reply

7 Jared December 13, 2012 at 9:05 am

Here’s one excerpted from a functions file, and modified to standalone.
It works in ksh and bash, don’t know about other shells.

ts20 > cat functions.sh/fqn.sh

function getScriptPath {
typeset SCRIPT=$1
STAT_RESULT=$(stat –format=%N $SCRIPT | sed -e “s/[\`']//g”)

if [ -L "$SCRIPT" ]; then
STAT_RESULT=$(echo $STAT_RESULT | awk ‘{ print $3 }’)
fi

echo $STAT_RESULT

echo $(getScriptPath $0)

ts20 > functions.sh/fqn.sh
functions.sh/fqn.sh

ts20 > ln -s /home/jkstill/shell/functions.sh/fqn.sh /tmp

ts20 > /tmp/fqn.sh
/home/jkstill/shell/functions.sh/fqn.sh

Reply

Leave a Comment

Tagged as: , , , , ,

Previous Faq:

Next Faq: