DBA Corner

Data is stored somewhere

Shell Script: Find the Script’s Own Directory

A script’s current working directory and the directory containing the script are different concepts. pwd reports where the caller is working; it does not reliably report where the script file lives.

Bash: directory containing the script

#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(
  cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1
  pwd -P
)"

printf 'Script directory: %s
' "$SCRIPT_DIR"

BASH_SOURCE[0] identifies the current Bash source file. dirname extracts its directory, and the subshell changes to that directory before pwd -P returns an absolute physical path. The caller’s directory is unchanged.

POSIX shell variant

#!/bin/sh

case $0 in
  */*) script_path=$0 ;;
  *)   script_path=$(command -v -- "$0") ;;
esac

SCRIPT_DIR=$(
  CDPATH= cd -P -- "$(dirname -- "$script_path")" && pwd -P
) || exit 1

printf 'Script directory: %s
' "$SCRIPT_DIR"

This version is useful for scripts intended for /bin/sh. It handles a command found through PATH, but it deliberately does not attempt to follow every symbolic-link chain.

Important edge cases

  • A sourced file should normally use the shell’s source-file feature; in Bash, that is BASH_SOURCE.
  • readlink -f can resolve links on systems that provide it, but it is not portable to every Unix platform.
  • Quote every path. Spaces, wildcard characters, and leading hyphens are valid in filenames.
  • A copied script can still discover the copied location; do not assume a fixed installation directory unless your deployment guarantees it.

The legacy version used which $0, which is inconsistent across platforms and can mis-handle aliases, shell functions, and unusual paths. Use the shell’s own command lookup and keep path expansion quoted.


Comments

Leave a Reply

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