To reliably determine the directory where a Bash script is located from within the script itself, use the following method:
#!/bin/bash
# Get the directory of the script itself, resolving symlinks
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd -P )"
echo "Script directory: $SCRIPT_DIR"
Explanation:
${BASH_SOURCE[0]}
:
- Refers to the path of the script being executed.
- More reliable than
$0
(which can return the shell name if the script is sourced).
dirname
:
- Extracts the directory path from the script’s full path.
- Example: If the script path is
/home/user/scripts/myscript.sh
,dirname
returns/home/user/scripts
.
cd -- "$(dirname ...)"
:
- Changes to the script’s directory.
--
ensures paths starting with-
are not treated as options.
pwd -P
:
- Prints the physical (resolved) directory, resolving symlinks.
-P
ensures the path is absolute and free of symbolic links.
- Error Suppression (
&> /dev/null
):
- Silences
cd
errors (e.g., if the directory is invalid).
Key Features:
- Symlink Safety: Resolves the actual directory even if the script is invoked via a symlink.
- Portability: Works across Linux, macOS, and other Unix-like systems.
- Robustness: Handles spaces and special characters in paths.
Example Usage:
If the script /opt/myapp/run.sh
is symlinked to /usr/local/bin/run
:
# Output when running via symlink:
# Script directory: /opt/myapp
Alternative (if pwd -P
is unavailable):
For systems without pwd -P
, use realpath
(if installed):
SCRIPT_DIR="$( dirname "$(realpath "${BASH_SOURCE[0]}")" )"
By using this approach, you ensure the script always knows its own directory, regardless of how it is executed.