Bash Scripting
  • scripting list
  • How to Make Bash Script Executable Using Chmod
  • Shell Script to Check Linux Server Health
  • How to Concatenate String Variables in Bash [Join Strings]
  • How to Do Bash Variable Substitution (Parameter Substitution)
  • Bash Parameter Expansion with Cheat Sheet
  • Bash getopts with Examples
  • How to Pass all Arguments in Bash Scripting
  • Bash Function Return Value
  • Bash Loop Through Lines in a File
  • Bash readarray with Examples
  • Bash let with Examples
  • Bash expr with Examples
  • Bash read password
  • Bash for Loop Range Variable
  • Bash Arrays Explained
  • Ways to Find Bash Array Length
  • Bash Split String by Delimiter
  • Bash if Options
  • Bash If Statements for String Comparison
  • Debugging Techniques for Bash Scripts
  • Determining if a Bash String is Empty
  • Bash if Statement with Multiple Conditions
  • Meaning of Shebang in Bash Scripts
  • How to Comment Code in Bash Script
  • How to Read CSV File in Bash
  • Bash Scripting: How to Check if File Exists
  • Bash If Else Statements: Examples and Syntax
  • Bash Scripting: How to Check if Directory Exists
  • Bash eval Command with Examples
  • How to Use Sleep Command in Bash Scripting
  • Bash Associative Arrays with Examples
  • Bash Script for Counting Lines in a File
  • How to Use While Loop in Bash for Efficient Scripting
  • Bash basename Command with Examples
  • How to Create Multiline Strings in Bash
  • How to Use Bash if With && Operator
  • 50 Bash Script Examples to Kickstart Your Learning
  • Case statement in Bash Shell Scripting
  • Trimming White Space in Bash
  • How to Extract Filename from Absolute Path in Bash
  • How to Get Directory Path in Bash
  • Extract Extension from File Path in Bash
  • Extract Filename without Extension from Full Path in Bash
  • Bash for Each File in a Directory
  • Bash for Loop with Array
  • Bash Continue – Using with for Loop
  • Bash Backticks vs Dollar Parentheses $()
  • How to Assign Variable in Bash
  • How to Assign Variable in Bash
  • Bash Division Explained
  • Bash Modulo (Division Remainder)
  • Bash While Read Line by Line
  • Bash shift Command
  • Bash Looping Through Array of Strings
  • Bash read Command with Examples
  • Bash Check Empty Array
  • Using Bash For Loops to Iterate Over a List of Strings
  • Bash Break – Using with For Loop
  • How to Use seq With for Loop in Bash
  • How to Use $@ in Bash Scripting
  • Get the Current Script Directory in Bash
Powered by GitBook
On this page
  • 1. Introduction
  • 2. Why not pwd?
  • 3. What is $0?
  • 4. Bash get the script directory
  • 5. Summing up

Get the Current Script Directory in Bash

PreviousHow to Use $@ in Bash Scripting

Last updated 1 year ago

1. Introduction

In Bash scripting, it's often useful to determine the directory in which a script is located. This information can be helpful for various tasks, such as accessing other files relative to the script or performing operations within the script's directory.

In this guide, we focus our attention on the two major special variables- $0 and BASH_SOURCE and combine them with the existing tools to get the current script's directory.

2. Why not pwd?

When running any Bash script, we effectively execute it in a subshell. It runs in a separate environment. This shell differs from the shell that we are using to run the script. The pwd command gives us the current working directory of the subshell rather than the directory containing the Bash script.

We can understand this with an example.

Create a script named dirScript1.sh in the directory /home/ubuntu/Downloads and add:

#!/bin/bashpwd

We execute the above script from /home/ubuntu/Desktop:

sh /home/ubuntu/Downloads/dirScript1.sh

When we run, the script generates the output which will be /home/ubuntu/Desktop. However, our script is located in /home/ubuntu/Downloads. Hence, we should be careful when dealing with the pwd command. It will return us the current working directory and not the directory of the Bash script.

3. What is $0?

We often encounter special variables in Bash scripts. $0 is one such variable containing the name of the current script that is under execution. It is also termed as the zeroth argument.

When a script begins its execution, Bash informs the interpreter. It sends the name of that script as the first argument. Then the $0 variable is set to the name of the script. It can include the path, if specified.

Let us try an example. We have a Bash script - dirScript2.sh located in the "/home/ubuntu/Downloads" directory with the below contents:

#!/bin/bashecho $0

We execute the script from the same location with the absolute path as follows:

sh /home/ubuntu/Downloads/dirScript2.sh

4. Bash get the script directory

We have to follow a step-by-step process to determine the script directory. We will understand this process in detail and learn where it can fail. We will also learn how to resolve the symbolic link, if present.

4.1 BASH_SOURCE variable

Another special Bash variable is the BASH_SOURCE. It is an array that stores the source file names corresponding to the executing script.

The first element of the array will be BASH_SOURCE[0]. It has the name of the current script. This will contain the same contents as $0, we saw above.

The BASH_SOURCE variable is useful when scripts are calling other scripts. We can determine the source of the current execution context by examining this array.

Example:

#!/bin/bashecho "My current script is: ${BASH_SOURCE[0]}"echo "My current script is: ${BASH_SOURCE}"echo "My parent is: ${BASH_SOURCE[1]}"echo "My grandparent is: ${BASH_SOURCE[2]}"echo "My great grandparent is: ${BASH_SOURCE[3]}"

The different indices of the BASH_SOURCE array variable contain the current script, the parent script, and so on. If the script is not invoked from any other script, the values of BASH_SOURCE[1], BASH_SOURCE[2], and BASH_SOURCE[3] will remain empty.

4.2 Dirname command

We have already learnt different ways to extract the name of the directory. A simple and effective way is to use the Bash built-in utility named dirname.

Example:

dirname /home/ubuntu/sample/dirA/A_file.txt

The dirname command first looks for the last path separator (/). It then displays whatever is present before that. It omits everything after that.

4.3 Putting everything together so far

Now that we are armed with the understanding of the $0 variable, the BASH_SOURCE variable and the dirname command, we can put everything into practice to get the source directory of any Bash script.

Example:

#!/bin/bashecho 'Script using $0 is: ' $0echo 'Script using BASH_SOURCE is: ' ${BASH_SOURCE} mydir=$(dirname "$0")echo 'Directory of the script: ' $mydir

Now let us run this script using the command:

sh /home/ubuntu/Downloads/dirScript4.sh

Using the $0 variable, we fetch the full path to the script. We also do the same using the other special array variable BASH_SOURCE. We then supply this to the dirname command. It helps to retrieve the directory portion from the path, which we store in the mydir variable. We finally print its contents.

4.4 Readlink command

The readlink command is a great tool in our armory to resolve symbolic links and get the desired path. It accepts one or more arguments. These arguments are the paths of symbolic links to be resolved.

It can be incorporated in Bash scripts for determining the directory path of the script. This is vital in scenarios where the script is invoked through a symbolic link or a relative path.

Upon executing any Bash script, the $0 variable will store the name of the script. It may not contain the entire absolute path to the script. Furthermore, if our script gets invoked through a symbolic link or a relative path, the $0 variable will contain the path to the link or the relative path.

This is where the readlink command comes to our rescue. It resolves any symbolic links and obtains the absolute path to the script.

Let us understand this with an example:

#!/bin/bash mydir="$(dirname "$0")"echo "The script directory without readlink is: $mydir" mydir="$(dirname "$(readlink -f "$0")")"echo "The script directory with readlink is: $mydir"

We run this script as:

./dirScript5.sh

The special parameter $0 contains the name of the file which is ./dirScript4.sh

In the first scenario we use the dirname command on $0 directly. This will simply trim everything after the path separator (/) and give us simply the dot ".". It will not expand the value of this dot.

In the next scenario, we employ the readlink command on $0 first. This helps obtain the absolute path of the script. During this process, it will also handle any symbolic links. Lastly, we bring the dirname into the picture to fetch the directory portion. We store this in the mydir variable and display its value.

The readlink command always ensures that we obtain the correct directory path of the script, regardless of how it is invoked.

4.5 Links

The BASH_SOURCE or the $0 variable may contain the path to the link and not the actual script path. For this we have to handle the link recursively and resolve it using the readlink command we saw above.

Example:

#!/bin/bash scriptPath="${0}"#scriptPath="${BASH_SOURCE}" while [ -L "${scriptPath}" ]do path="$(readlink "${scriptPath}")" if [[ "${path}" == /* ]] then scriptPath="$path" else scriptPath="$(dirname "${scriptPath}")/${path}" fi done echo "scriptPath=${scriptPath}"

The variable scriptPath has the value of the currently executing script. We are using a while loop with the -L flag. This will run till this variable is a symbolic link. This loop helps to resolve any symbolic links in the path and obtain the absolute path to the script.

For every run of this loop, we have the readlink command to get the path of the symbolic link. If this path is an absolute path ("/"), our scriptPath becomes the value present in the path variable. If not, the dirname command extracts the directory part from the scriptPath. It appends the path variable to it. This results in the creation of the absolute path.

This is an important aspect as symbolic links can also use relative paths. This needs to be resolved relative to the directory containing the link. After the loop ends, we print the scriptPath. It will hold the absolute path to the script. All symbolic links will be resolved.

5. Summing up

Let us sum up the process of finding the directory path of the bash script into 3 simple steps:

  1. Use the $0 or the BASH_SOURCE special variable to get the script name with the path.

  2. Using the readlink command, obtain the absolute path and resolve symbolic links

  3. Use dirname command to extract the directory.

Our scripting is simply echoing $0. It has the value /home/ubuntu/Downloads/dirScript2.sh. To from this, we can use the dirname command.

extract the directory path