How to get the directory where a Bash script is located from within the script itself?

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:

  1. ${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).
  1. 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.
  1. cd -- "$(dirname ...)":
  • Changes to the script’s directory.
  • -- ensures paths starting with - are not treated as options.
  1. pwd -P:
  • Prints the physical (resolved) directory, resolving symlinks.
  • -P ensures the path is absolute and free of symbolic links.
  1. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *