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
Difficulty Easy (rss)
Root privileges No
Requirements Unix like+
Time N/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.


Create a shell script as follows:

# 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.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 9 comments so far... add one

CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
9 comments… add one
  • Nikesh Dec 11, 2012 @ 13:23

    # Dir in which bash script is
    echo `pwd`

    # name of bash script file
    echo `$0

    • kustodian Dec 11, 2012 @ 19:51

      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/ and it contains:

      echo `pwd`
      echo $0

      then if you run the following commands:

      cd /tmp

      the script will print:


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

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

  • Andy Dec 11, 2012 @ 13:41

    I tend to use

    _base=$(cd $(dirname $0); pwd -P)
    • 🐧 nixCraft Dec 11, 2012 @ 13:53

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

  • Shantanu Gadgil Dec 12, 2012 @ 6:34

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


    • kustodian Dec 12, 2012 @ 23:47

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

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

      echo ${0##*/}
  • Jared Dec 13, 2012 @ 9:05

    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

    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 }’)

    echo $STAT_RESULT

    echo $(getScriptPath $0)

    ts20 >

    ts20 > ln -s /home/jkstill/shell/ /tmp

    ts20 > /tmp/

  • hamis jumanne Apr 22, 2014 @ 11:35

    please help me on this how can i locate a file in any subdirectories , give its details, and show the path of its existence

  • Johny Why May 12, 2015 @ 6:20

    this works great for me:
    `dirname $0`
    love the brevity. any caution against using this form?
    i believe $0 does not work as expected if sourcing a file, but i know of no other problem with this form.


Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Problem posting comment? Email me @