MWCodebymw.de ↗
Terminal

Standardwerte und Pflichtvariablen in Bash – ${VAR:-…} und ${VAR:?…}

Fehlt eine Umgebungsvariable, läuft das Skript oft trotzdem los – und löscht dann /backup/ statt /backup/kunde42/. Die Shell kann Standardwerte setzen und fehlende Werte laut einfordern, ohne eine einzige if-Abfrage.

Der gefährlichste Fehler in Shell-Skripten ist die leere Variable:

rm -rf "$ZIEL/alt"     # ZIEL ist leer → rm -rf "/alt"

Bash hat für genau diese Fälle eine eigene Syntax – kompakt, und schon eingebaut.

Standardwert, wenn nichts gesetzt ist

port="${PORT:-8080}"           # PORT, sonst 8080
umgebung="${ENV:-produktiv}"
ziel="${1:-$PWD}"              # erstes Argument, sonst aktuelles Verzeichnis

Der Doppelpunkt ist wichtig: ${VAR-wert} greift nur, wenn die Variable gar nicht existiert; ${VAR:-wert} auch, wenn sie leer ist. In der Praxis willst du fast immer die Variante mit Doppelpunkt.

Zuweisen statt nur einsetzen

: "${LOGDIR:=/var/log/meinapp}"   # setzt LOGDIR, falls leer – und behält es
mkdir -p "$LOGDIR"

:= schreibt den Wert in die Variable zurück, damit die nächsten zwanzig Zeilen ihn benutzen können. Das : davor ist der Nichts-tu-Befehl – er sorgt dafür, dass die Expansion nicht als Kommando ausgeführt wird.

Pflichtangaben laut einfordern

: "${API_TOKEN:?API_TOKEN ist nicht gesetzt}"
: "${ZIEL:?Bitte ZIEL angeben, z. B. ZIEL=/srv/backup}"

Fehlt der Wert, bricht das Skript sofort mit genau dieser Meldung ab – in Zeile 3 statt in Zeile 80, und mit einem Text, den auch jemand versteht, der das Skript nicht geschrieben hat.

Zuschneiden: Endungen, Pfade, Präfixe

datei="/var/www/bericht.tar.gz"

echo "${datei##*/}"     # bericht.tar.gz   (alles bis zum letzten /)
echo "${datei%/*}"      # /var/www         (Verzeichnis)
echo "${datei%.gz}"     # …/bericht.tar    (kürzeste Endung weg)
echo "${datei%%.*}"     # /var/www/bericht (ab dem ersten Punkt weg)

Merkhilfe: # schneidet vorn (wie beim Kommentarzeichen am Zeilenanfang), % hinten (wie beim Prozent am Ende). Einfach = kürzest möglich, doppelt = längst möglich.

Ersetzen und Länge

name="kunde-42-rechnung"
echo "${name/-/_}"       # kunde_42-rechnung   (erstes Vorkommen)
echo "${name//-/_}"      # kunde_42_rechnung   (alle)
echo "${#name}"          # 18                  (Länge)
echo "${name^^}"         # KUNDE-42-RECHNUNG   (Großbuchstaben)

Das spart in Schleifen erstaunlich viele Aufrufe von sed und tr – und jeder vermiedene externe Prozess ist bei 10.000 Dateien messbar.

Fallstrick

${VAR:?…} bricht ab, indem es die Shell beendet – in einer interaktiven Sitzung schließt das dein Terminal-Fenster. Zum Ausprobieren also lieber in einem Skript oder in einer Subshell ( … ). Und noch ein Klassiker: ${1:-$PWD} hilft nicht gegen set -u, wenn du später doch $2 ansprichst – bei optionalen Argumenten immer mit Standardwert zugreifen, nie direkt.

Skripte, die freundlich abbrechen statt still Unsinn zu tun, sind kein Luxus. Wenn du Automatisierung brauchst, die man auch Kollegen geben kann: bymw.de.

Quellen

#Bash#Parameter Expansion#Umgebungsvariablen#Skripte#Robustheit

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →