Get Script Directory Location in Bash

In a situation where your bash script needs to get the directory location where it is located?

In this tutorial, I'll be sharing multiple scenarios and in the end, will give you a universal way to get the script directory location from the bash script itself.

How to get script directory location in bash

There are multiple scenarios you need to keep in mind while writing a part of the script to get the location of the script:

  • Path (relative or absolute)
  • Whether the script is called through the symlink

So how do we get there? Let's have a look at step by step.

1. Get the name of the script using BASH_SOURCE[0]

You might be wondering, why not use the special variable $0 to do so? Well, there's a strong reason behind this.

There are two ways to execute the bash script:

  • By sourcing it
  • By executing it

And when you use the $0 variable in the script and execute it, it won't print the filename.

As I intend to make a universal solution, I'm skipping using the $0 variable.

So here, I'll be using the BASH_SOURCE[0] variable which does the same job but gives more predictable results.

Let's start the script by printing the value of the BASH_SOURCE variable:

#!/bin/bash

echo "${BASH_SOURCE}"

Now, even if you source the file, it will give you the path and the filename.

For example, here, I created this file inside the Test directory, and when I sourced it from my home directory, it gave me this:

But if I change the directory where the file is located and then execute the file, then, it will only print the filename:

So in the next section, I will show you how you can get the absolute path irrespective of where the file was executed.

In case you don't know, symbolic links can behave as a shortcut to a file so if you created a symlink to a file then how it will handle the path?

Sounds complex? Let's have a look at the problem that we are trying to solve here.

Here, I have created a symbolic link inside my home directory pointing to Test/location.sh.

And when I executed the script via a symbolic link, it assumed that the file is in the current working directory (the home directory in my case):

But what if I tell you that you can follow the symbolic link to its original file and get the absolute path at the same time?

Yes, you can deal with both of them at the same time.

For that purpose, I will be using the readlink command with the -f flag:

#!/bin/bash

Dir_path="$(readlink -f "${BASH_SOURCE}")"
echo "Script location is: $Dir_path"

Here, I have used the readlink and assigned the value to the Dir_path variable.

And in the end, used little statements which would make the output more human-readable:

As you can see, from now on, you can use the symlinks too and it will get the correct path.

In a similar, related post, do you use the super useful brace expansions in your scripts?

Using Brace Expansion in Bash Shell
Brace expansion in the bash shell is a lesser known but an awesome feature. Learn about using them like a Pro Linux user with practical examples.

Let me know if I was able to help you get the directory location in bash script.