DEV Community

Cover image for How to Get the Directory Where a Bash Script is Located
Bobby Iliev
Bobby Iliev

Posted on • Originally published at devdojo.com

How to Get the Directory Where a Bash Script is Located

Hello everyone!

When you're working with Bash scripts, it's often useful to know the directory where the script itself resides. This can be essential for referencing relative paths, ensuring the script works correctly regardless of where it is executed from. Let’s dive into how you can achieve this.

Method 1: Using dirname and $0

The simplest way to get the directory of the script is to use the dirname command in combination with $0. Here's a step-by-step explanation:

  1. $0: This special variable contains the path used to invoke the script. It might be a relative path, an absolute path, or just the script name.
  2. dirname: This command removes the last component from a path, effectively giving you the directory part.

Here’s a small snippet to demonstrate this:

#!/bin/bash

# Get the directory of the script
SCRIPT_DIR=$(dirname "$0")

echo "The script is located in: $SCRIPT_DIR"
Enter fullscreen mode Exit fullscreen mode

Method 2: Resolving the Full Path

If you need the absolute path, especially if the script is run from a relative path, you can combine dirname with readlink:

#!/bin/bash

# Resolve the full path of the script
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")

echo "The script is located in: $SCRIPT_DIR"
Enter fullscreen mode Exit fullscreen mode

Breaking Down the Command

  • readlink -f "$0": This command follows all symlinks and returns the absolute path of the script.
  • dirname "$(readlink -f "$0")": This gives the absolute directory path of the script.

Method 3: Handling Edge Cases

For more complex scenarios, such as when the script is sourced or if it's part of a symlink chain, you might need additional logic to ensure you always get the correct directory.

Here’s an advanced version that handles more edge cases:

#!/bin/bash

# Function to resolve the script path
get_script_dir() {
    local SOURCE=$0
    while [ -h "$SOURCE" ]; do # Resolve $SOURCE until the file is no longer a symlink
        DIR=$(cd -P "$(dirname "$SOURCE")" && pwd)
        SOURCE=$(readlink "$SOURCE")
        [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # If $SOURCE was a relative symlink, resolve it relative to the symlink base directory
    done
    DIR=$(cd -P "$(dirname "$SOURCE")" && pwd)
    echo "$DIR"
}

# Get the directory
SCRIPT_DIR=$(get_script_dir)

echo "The script is located in: $SCRIPT_DIR"
Enter fullscreen mode Exit fullscreen mode

Conclusion

Getting the directory of the Bash script from within the script itself is a common requirement and can be easily achieved using dirname and $0. For more robust solutions, combining these with readlink can ensure you handle absolute paths and symlinks correctly. By incorporating these methods into your scripts, you can make them more portable and easier to manage.

If you’re interested in learning more about Bash scripting, be sure to check out my free eBook on Bash scripting. It's packed with useful information and examples to help you become a Bash scripting pro!

Happy scripting!

Top comments (9)

Collapse
 
kubeden profile image
Kuberdenis

Great post as always, Bobby!! Would the which command would work 🤔 Maybe if I add my script to /usr/local/bin /bin it will automatically fall into the which command logic, what do you think?

Collapse
 
bobbyiliev profile image
Bobby Iliev

Thanks for the feedback @kubeden 🙌

Yep, the which command can be used to find the location of an executable in your PATH, but it has some limitations for this particular case.

If you add your script to directories like /usr/local/bin or /bin, which can tell you where it’s located when executed, but it doesn't handle relative paths or symlinks as well as dirname and readlink. Here’s how you might use it:

#!/bin/bash

# Get the full path of the script
SCRIPT_PATH=$(which "$(basename "$0")")

echo "The script is located in: $SCRIPT_PATH"
Enter fullscreen mode Exit fullscreen mode

However, for more robustness, especially with symlinks and relative paths, I’d still recommend using the dirname and readlink approach. This is also particularly helpful if your script is going to be executed by other users on their local machines and you would not know where they would store the script.

Collapse
 
kubeden profile image
Kuberdenis

I think I need to read more about symlinks, relative paths, and why “everything is a file in linux”

I need to go through your book

Collapse
 
josephj11 profile image
Joe

I use this:

function mypath () {
  ## Get the real path of the calling script
  ##  From: https://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within/246128#246128
  my_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
}

Enter fullscreen mode Exit fullscreen mode

I don't remember the details, but it works.

I don't have a lot of symlinks to symlinks, so I'm not sure if this would fail when your third method would succeed.

The reason why I need this at all is that I invoke a lot of scripts from the GUI, and, occasionally, from a special directory. The GUI doesn't have $HOME/bin in its PATH and so scripts that call other scripts have to be able to find them by themselves.

Collapse
 
bobbyiliev profile image
Bobby Iliev

This is pretty cool! Thank you for sharing! 👏

Collapse
 
vsaulis profile image
Vladas Saulis

It was very nice command: whereis .

Collapse
 
drhyde profile image
David Cantrell • Edited

An alternative way of resolving symlinks:

SCRIPT_DIR="$( cd "$(dirname "$0")"; pwd -P)"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
andrea_from_italy profile image
andrea_fazzi

Thank you!

Collapse
 
manzella profile image
Hana Manzella

so much for learning! AI HELP ))