Variablen & Parameter
Bash-Variablen, Arrays, assoziative Arrays und die maechtige Parameter-Expansion mit Defaults, Substrings und Ersetzungen.
Inhaltsverzeichnis
Variablen & Parameter in Bash
Bash ist dynamisch typisiert - alle Variablen sind im Kern Strings. Aber die Parameter-Expansion bietet viele Tricks, um mit ihnen zu arbeiten.
Variablen setzen
name="Anna"
alter=28
pfad="/home/anna"
Regeln:
- Kein Leerzeichen um
=:name="Anna", nichtname = "Anna" - Keine Typ-Angabe
- Gross-/Kleinschreibung signifikant
- Konvention:
snake_caseoderUPPER_CASEfuer Umgebungsvariablen / Konstanten
Variablen nutzen
echo "$name" # "Anna"
echo "${name}" # genauso
echo "Hallo, $name!" # "Hallo, Anna!"
echo "Hallo, ${name}!" # genauso
echo '$name' # "$name" literal (single quotes!)
Die geschweiften Klammern ${var} sind besonders wichtig, wenn direkt danach Buchstaben folgen:
dateibasis="backup"
echo "$dateibasis_final" # FEHLER: sucht Variable $dateibasis_final
echo "${dateibasis}_final" # "backup_final"
export - fuer Umgebungsvariablen
name="Anna" # nur in dieser Shell
export API_KEY="geheim" # auch an Kind-Prozesse
export macht eine Variable fuer alle von dieser Shell gestarteten Programme sichtbar. Ohne export sieht der gestartete Python-Prozess die Variable nicht.
Lokal in Funktionen
my_funktion() {
local temp="nur hier"
echo "$temp"
}
Immer local in Funktionen - sonst ueberschreibst du globale Variablen.
Parameter-Expansion - die Superkraft
Bash hat eine ganze Mini-Sprache fuer Variable-Operationen.
Default-Werte
name="${1:-Anonym}" # wenn $1 leer/nicht gesetzt, nimm "Anonym"
port="${PORT:-3000}" # Environment mit Default
# Fehler mit Meldung statt Default:
name="${1:?Bitte einen Namen uebergeben}"
Varianten:
${var:-default}- Default, wenn leer oder nicht gesetzt${var-default}- Default nur wenn nicht gesetzt (leer ist OK)${var:=default}- wie:-, aber weist auch zu${var:?meldung}- Fehler werfen, wenn leer
Laenge
name="Anna"
echo "${#name}" # 4
Substring
text="Hallo, Welt!"
echo "${text:0:5}" # "Hallo"
echo "${text:7}" # "Welt!"
echo "${text: -5}" # "Welt!" (Leerzeichen vor Minus!)
Suchen und Ersetzen
datei="foto.jpg"
echo "${datei/.jpg/.png}" # "foto.png" (erstes Vorkommen)
echo "${datei//o/O}" # "fOtO.jpg" (alle Vorkommen)
echo "${datei#foto.}" # "jpg" (Praefix entfernen)
echo "${datei%.jpg}" # "foto" (Suffix entfernen)
Praktisch: Dateiname zerlegen
pfad="/home/anna/foto.jpg"
basis="${pfad##*/}" # "foto.jpg" (Dateiname)
dir="${pfad%/*}" # "/home/anna" (Verzeichnis)
ohne_ext="${basis%.*}" # "foto"
endung="${basis##*.}" # "jpg"
Das sind die Bash-Aequivalente zu dirname / basename - und schneller, weil keine externen Prozesse noetig sind.
Case-Umwandlung
name="anna"
echo "${name^}" # "Anna" (ersten Buchstaben gross)
echo "${name^^}" # "ANNA" (alles gross)
echo "${name,}" # "anna" (erster klein)
echo "${name,,}" # "anna" (alles klein)
Erst seit Bash 4+.
Arrays
Indizierte Arrays:
namen=("Max" "Anna" "Leo")
echo "${namen[0]}" # "Max"
echo "${namen[2]}" # "Leo"
echo "${namen[@]}" # "Max Anna Leo" (alle)
echo "${#namen[@]}" # 3 (Anzahl)
namen+=("Tim") # anhaengen
unset 'namen[1]' # entfernen (Luecke!)
Iterieren
for name in "${namen[@]}"; do
echo "Hallo, $name!"
done
Wichtig: Immer "${array[@]}" mit Quotes - sonst gehen Leerzeichen in Elementen kaputt.
Assoziative Arrays (Bash 4+)
declare -A alter
alter["Anna"]=28
alter["Max"]=34
alter["Leo"]=22
echo "${alter[Anna]}" # 28
echo "${#alter[@]}" # 3
echo "${!alter[@]}" # Keys: "Anna Max Leo"
for name in "${!alter[@]}"; do
echo "$name ist ${alter[$name]}"
done
Assoziative Arrays sind ein oft uebersehener Bash-Schatz.
Arithmetik
Zahlen mit $(( ... )):
a=5
b=3
summe=$((a + b))
produkt=$((a * b))
modulo=$((a % b))
potenz=$((a ** b))
echo "$summe $produkt $modulo $potenz"
# 8 15 2 125
Oder let:
let c=a+b
Oder (( ... )) fuer Konditionen:
if (( a > b )); then
echo "groesser"
fi
Wichtig: Bash rechnet nur mit Ganzzahlen! Fuer Gleitkomma brauchst du bc oder awk:
echo "scale=2; 10/3" | bc
# 3.33
Die speziellen Variablen
echo "$0" # Skript-Name
echo "$1" # erstes Argument
echo "$2" # zweites
echo "$@" # alle Argumente (separat)
echo "$*" # alle Argumente (als ein String)
echo "$#" # Anzahl Argumente
echo "$?" # Exit-Code des letzten Kommandos
echo "$$" # PID des Skripts
echo "$!" # PID des letzten Background-Prozesses
Immer "$@" (mit Quotes) zum Iterieren - das behandelt Leerzeichen korrekt.
Umgebungsvariablen
Wichtige Standard-Variablen:
echo "$HOME" # /home/anna
echo "$USER" # anna
echo "$PATH" # Suchpfad
echo "$PWD" # Aktuelles Verzeichnis
echo "$SHELL" # deine Login-Shell
echo "$TERM" # Terminal-Typ
echo "$LANG" # Locale
Praktisches Beispiel
#!/usr/bin/env bash
set -euo pipefail
# Dateien in einem Ordner umbenennen - mit Praefix
# Aufruf: ./rename.sh <ordner> [praefix]
ordner="${1:?Ordner angeben}"
praefix="${2:-datei}"
if [[ ! -d "$ordner" ]]; then
echo "Ordner existiert nicht: $ordner" >&2
exit 1
fi
zaehler=0
for datei in "$ordner"/*; do
[[ -f "$datei" ]] || continue
basis="${datei##*/}"
endung="${basis##*.}"
ziel="${ordner}/${praefix}-$((++zaehler)).${endung}"
mv "$datei" "$ziel"
echo " $basis -> ${ziel##*/}"
done
echo "$zaehler Dateien umbenannt."
Was ist hier zu sehen?
${1:?Ordner angeben}- Pflicht-Parameter mit Fehlermeldung${2:-datei}- Default-Wert${datei##*/}und${basis##*.}- Pfad-Zerlegung via Parameter-Expansion(( ++zaehler ))- Ganzzahl-Inkrement- Quoting ueberall - damit Leerzeichen in Dateinamen OK sind
Zusammenfassung
- Variablen ohne Leerzeichen:
name="Anna" "$var"in Quotes nutzen,${var}bei Bedarf- Parameter-Expansion: Defaults
:-, Substrings, Ersetzungen, Trimming exportmacht Variablen an Kind-Prozesse sichtbar,localin Funktionen- Indizierte und assoziative Arrays (
declare -A) - Arithmetik mit
$((...)), nur Ganzzahlen - Immer
"$@"zum Iterieren ueber Argumente
Im naechsten Kapitel: Kontrollstrukturen und Tests.