Erklärung: ========= Gerne. Die Zeile sieht auf den ersten Blick ziemlich kompliziert aus, macht aber eigentlich nur einen Schritt nach dem anderen: SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" Das Ziel ist: Den absoluten Pfad des Verzeichnisses ermitteln, in dem das Bash-Script liegt, und ihn in SCRIPT_DIR speichern. 1. ${BASH_SOURCE[0]} ${BASH_SOURCE[0]} BASH_SOURCE ist ein Bash-Array, das Informationen darüber enthält, aus welcher Script-Datei der aktuelle Code stammt. [0] bedeutet: erstes Element. Beispiel: /home/user/scripts/test.sh Dann liefert: echo "${BASH_SOURCE[0]}" zum Beispiel: /home/user/scripts/test.sh Das ist robuster als $0, insbesondere wenn Scripts weitere Scripts einbinden (source). 2. dirname Jetzt kommt: dirname -- "${BASH_SOURCE[0]}" dirname entfernt den Dateinamen und lässt nur das Verzeichnis übrig. Aus: /home/user/scripts/test.sh wird: /home/user/scripts Das -- bedeutet: Ab hier kommen keine Optionen mehr, sondern Argumente. Das ist eine kleine Sicherheits-/Robustheitsmaßnahme. 3. Die äußere $(...) Wir haben jetzt: $(dirname -- "${BASH_SOURCE[0]}") $(...) bedeutet in Bash: Führe diesen Befehl aus und setze seine Ausgabe hier ein. Also beispielsweise: $(dirname -- "${BASH_SOURCE[0]}") wird zu: /home/user/scripts Damit haben wir effektiv: cd -- "/home/user/scripts" 4. cd Jetzt kommt: cd -- "$(dirname -- "${BASH_SOURCE[0]}")" Damit wechseln wir temporär innerhalb einer Subshell in das Script-Verzeichnis. Warum cd? Weil wir anschließend mit pwd den absoluten Pfad dieses Verzeichnisses ermitteln können. 5. && Der Teil: cd -- "..." && pwd bedeutet: Führe pwd nur dann aus, wenn cd erfolgreich war. Also: cd erfolgreich? │ ├── ja → pwd ausführen │ └── nein → pwd nicht ausführen Das ist besser, als einfach beide Befehle unabhängig voneinander auszuführen. 6. pwd pwd steht für print working directory. Es gibt das aktuelle Arbeitsverzeichnis aus. Wenn wir vorher mit cd nach /home/user/scripts gewechselt haben, liefert: pwd eben: /home/user/scripts 7. Die äußere $(...) Jetzt haben wir: $(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) Wieder bedeutet $(...): Nimm die Ausgabe des Befehls und setze sie hier ein. Die Ausgabe ist beispielsweise: /home/user/scripts 8. Zuweisung an SCRIPT_DIR Ganz außen steht: SCRIPT_DIR="..." Damit wird der ermittelte Pfad in der Variable gespeichert: SCRIPT_DIR="/home/user/scripts" Du kannst anschließend beispielsweise schreiben: echo "$SCRIPT_DIR" oder: CONFIG_FILE="$SCRIPT_DIR/config.conf" Zusammengesetzt Man kann die ursprüngliche Zeile gedanklich in diese Schritte zerlegen: # 1. Wo liegt das Script? SCRIPT="${BASH_SOURCE[0]}" # 2. Nur das Verzeichnis davon DIR="$(dirname -- "$SCRIPT")" # 3. In dieses Verzeichnis wechseln cd -- "$DIR" # 4. Absoluten Pfad ausgeben ABSOLUTE_DIR="$(pwd)" # 5. In SCRIPT_DIR speichern SCRIPT_DIR="$ABSOLUTE_DIR" Die ursprüngliche Zeile fasst diese Schritte lediglich zusammen: SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" Warum die vielen "..."? Die Anführungszeichen sind wichtig, wenn ein Pfad Leerzeichen enthält. Zum Beispiel: /home/user/Meine Projekte/test.sh Ohne korrekt gesetzte Anführungszeichen könnte Bash daraus mehrere Argumente machen. Mit "${BASH_SOURCE[0]}" und "$(dirname ...)" wird der komplette Pfad als ein Argument behandelt. Kurzform zum Merken: BASH_SOURCE[0] ↓ Pfad zum Script ↓ dirname ↓ Verzeichnis des Scripts ↓ cd ↓ in dieses Verzeichnis wechseln ↓ pwd ↓ absoluten Pfad ermitteln ↓ SCRIPT_DIR Ein wichtiger Punkt dabei: cd verändert hier nicht dein eigentliches Arbeitsverzeichnis des aufrufenden Terminals, weil $(...) in einer Subshell ausgeführt wird. Das ist einer der Gründe, warum diese Konstruktion so praktisch ist.