objectif
Récupérer le chemin absolu du script Bash, même lancé depuis un autre dossier et même si le script est un symlink. Utile pour charger des ressources relatives (configs, templates) ou positionner la racine de projet.
code minimal
#!/usr/bin/env bash
set -Eeuo pipefail
get_script_dir() {
local src="${BASH_SOURCE[0]}"
while [ -h "$src" ]; do
local dir
dir="$(cd -P "$(dirname "$src")" && pwd)"
src="$(readlink "$src")"
[[ "$src" != /* ]] && src="$dir/$src"
done
cd -P "$(dirname "$src")" && pwd
}
SCRIPT_DIR="$(get_script_dir)"
echo "script dir: $SCRIPT_DIR"
utilisation
# accéder à un fichier voisin quel que soit le dossier courant
CONFIG="$SCRIPT_DIR/config/app.conf"
[ -r "$CONFIG" ] || { echo "config introuvable: $CONFIG" >&2; exit 1; }
# positionner la racine du projet et exécuter une commande
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
(cd "$PROJECT_ROOT" && make -s build)
# sourcer des utilitaires à côté du script
. "$SCRIPT_DIR/lib.sh"
# écrire un fichier de sortie à côté du script (écriture atomique)
tmp="$(mktemp -p "$SCRIPT_DIR" .out.XXXXXX)"
generate_content > "$tmp" && mv -f "$tmp" "$SCRIPT_DIR/output.txt"
variante(s) utile(s)
# utiliser realpath si disponible (plus simple)
if command -v realpath >/dev/null 2>&1; then
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
fi
# détecter si le script est exécuté directement ou sourcé
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
echo "exécuté: $0"
else
echo "sourcé depuis: $0"
fi
# fallback POSIX (moins robuste: ne suit pas les symlinks complexes)
POSIX_DIR="$(cd "$(dirname "$0")" && pwd)"
echo "posix dir (approx): $POSIX_DIR"
notes
- fonctionne en Bash (Linux/macOS). Évitez
readlink -fqui n’existe pas sur macOS. - renvoie un chemin absolu et canonique (
cd -Psuit les dossiers réels). ${BASH_SOURCE[0]}pointe vers le fichier courant même quand le script est sourcé.- pour zsh, utilisez
${(%):-%N}à la place de${BASH_SOURCE[0]}si nécessaire.