≡ Menu

Linux / Unix: Shell Script Find Out In Which Directory Script File Resides

I need to find out in which directory my bash script resides so that I can read config file called .backup .ignore .target. For example, if my script resides in >/home/foo/script.sh, I need to read /home/foo/.{backup,ignore,target} files. How do I find out the current directory location and shell script directory location in Bash running on Linux or Unix like operating systems?

Tutorial details
DifficultyEasy (rss)
Root privilegesNo
Estimated completion timeN/A
You can use any one of the following method to find out the portion of pathname:

  1. basename command - Display filename portion of pathname.
  2. dirname command - Display directory portion of pathname.
  3. Bash parameter substitution.
  4. $0 expands to the name of the shell or shell script.

Examples: Shell script find out which directory the script file resides

The following example display directory path or portion of /home/nixcraft/scripts/foo.sh:

dirname /home/nixcraft/scripts/foo.sh

Sample outputs:


The following line sets the shell variable i to /home/nixcraft/scripts:

i=`dirname /home/nixcraft/scripts/foo.sh`
echo "$i"


i=$(dirname /home/nixcraft/scripts/foo.sh)
echo "$i"

In bash script use $0 instead of /home/nixcraft/scripts/foo.sh:

basename="$(dirname $script)"
echo "Script name $script resides in $basename directory."

Sample outputs:

Script name /tmp/test.sh resides in /tmp directory.

Using bash shell ${var%pattern} syntax

To Remove from shortest rear (end) pattern use the following syntax:


For example:

echo "${x%/*}"
echo "$y"

An updated version of the above script:

# Purpose : Linux / Unix shell script find out which directory this script file resides
# Author : nixCraft <http://www.cyberciti.biz> under GPL v2.x+
# -------------------------------------------------------------------------------------
echo "Script name $script resides in $basename directory."
echo "Reading config file $config1 $config2 $config3, please wait..."

Sample outputs:

Fig.01 Sample run from test.sh

Fig.01 Sample run from test.sh

A note about finding physical or real path

You may not get a real physical path and real path may be a symbolic link. To get physical path use realpath command. The realpath command uses the realpath() function to resolve all symbolic links, extra / characters and references to /./ and /../ in path. This is useful for shell scripting and security related applications.

Another recommended option is to use the readlink command to display value of a symbolic link or canonical file name:

# Purpose : Linux / Unix shell script find out which directory this script file resides
# Author : nixCraft <http://www.cyberciti.biz> under GPL v2.x+
# -------------------------------------------------------------------------------------
## Who am i? ##
## Get real path ##
_script="$(readlink -f ${BASH_SOURCE[0]})"
## Delete last component from $_script ##
_mydir="$(dirname $_script)"
## Delete /path/to/dir/ component from $_script ##
_myfile="$(basename $_script)"
echo "Script : $_script"
echo "Directory portion of $_script : $_mydir"
echo "Filename portion of $_script : $_myfile"

Save and close the file. Run it as follows:

cd /home/vivek/

Sample outputs:

Fig.02: Finding real path

Fig.02: Finding real path

See also
Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 10 comments… add one }

  • Russ Thompson August 5, 2013, 12:40 am

    i found aund used the function below. This should be included in the script itself.

    getScriptPath() {
        if [ -d ${0%/*} ]
            abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
            # to get the path only - not the script name - add
            pathOnly=`dirname "$abspath"`
            progdir=`dirname $0`
            cd $progdir
        echo $pathOnly;

    Further down in the script I can use $(getScriptPath) as variable, such as

    mysql database <$(getScriptPath)/query.sql

    Hope this helps:

    • nixCraft August 12, 2013, 11:40 am

      Russ, I appreciate that you are sharing your code with us.

  • Mahdi August 5, 2013, 6:35 am

    Thank you for this!

  • Michel Nicolas August 6, 2013, 10:46 am


    The problem is that method won’t give your the absolute path if it is started with the relative one.
    For example, if my script is launched with ./test.sh I won’t know from the script where am I really residing in the FS.

    So the response is :
    abspath=$(readlink -f $0)

    Then you can do any basename, dirname an other path manipulation on it.

    • nixCraft August 12, 2013, 11:41 am

      Thanks for the heads up. The faq has been updated. I appreciate your post.

  • Chris F.A. Johnson August 18, 2013, 11:17 pm

    If a script needs to know where it is located, it is badly designed.

    • Michel Nicolas August 19, 2013, 5:04 am


      Can you tell me why would it be badly designed? Jugement without deep knowledge about the facts are useless.


      • Russ Thompson October 16, 2013, 3:48 pm

        I feel if a script has to be edited when moved from directory to directory to operate correctly it is badly designed.

        • Chris F.A. Johnson October 16, 2013, 6:15 pm

          If a script has to be moved from directory to directory, it is badly designed. Scripts should always be placed in a directory in your PATH variable, so they can be called from anywhere.

  • Latchezar Tzvetkoff October 16, 2013, 12:55 pm

    readlink -f $0 won’t work on Mac OS X.
    A nice one-liner would be

    SCRIPT_PATH=$(cd $(dirname ${0}) && pwd)

    It doesn’t resolve the real path, though. For this you’ll need an OS check or something…

    SCRIPT_PATH=$(cd $(dirname ${0}) && pwd)
    echo $SCRIPT_PATH
    if [[ ${OSTYPE} = darwin* ]]; then
    	TEMP=`readlink ${SCRIPT_PATH}`
    	echo $TEMP
    	SCRIPT_PATH=`readlink -f ${SCRIPT_PATH}`

    Note that OS X’s readlink is not reliable.

Leave a Comment