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 VerzeichnisDer 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
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 →Verwandte Snippets
Heredocs in Bash – mehrzeilige Texte, Konfigurationen und SQL ohne Echo-Wüste
Zwanzig echo-Zeilen für eine Konfigurationsdatei sind mühsam und fehleranfällig. Ein Heredoc schreibt den Text so, wie er aussehen soll – mit oder ohne Variablen, je nachdem, wie du den Marker schreibst.
Warum "$@" in Anführungszeichen gehört – Quoting und Arrays in Bash
Ein Dateiname mit Leerzeichen, und aus einem Argument werden zwei. Das ist keine Kleinigkeit: Genau daraus entstehen Skripte, die die falsche Datei löschen. Die Regeln dafür passen auf eine Seite.
trap und mktemp – Skripte, die auch nach einem Abbruch aufräumen
Ein Skript legt eine temporäre Datei an, bricht in der Mitte ab – und die Datei bleibt liegen. Nach ein paar Wochen ist /tmp voll und niemand weiß, woher der Müll kommt. Zwei Zeilen lösen das dauerhaft.