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:
-
$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. -
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"
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"
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"
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)
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 thewhich
command logic, what do you think?Thanks for the feedback @kubeden 🙌
Yep, the
which
command can be used to find the location of an executable in yourPATH
, 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 asdirname
andreadlink
. Here’s how you might use it:However, for more robustness, especially with symlinks and relative paths, I’d still recommend using the
dirname
andreadlink
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.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
I use this:
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.
This is pretty cool! Thank you for sharing! 👏
It was very nice command: whereis .
An alternative way of resolving symlinks:
Thank you!
so much for learning! AI HELP ))