Zum Inhalt springen
Bash Anfรคnger 25 min

Variablen & Parameter

Bash-Variablen, Arrays, assoziative Arrays und die maechtige Parameter-Expansion mit Defaults, Substrings und Ersetzungen.

Aktualisiert:
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", nicht name = "Anna"
  • Keine Typ-Angabe
  • Gross-/Kleinschreibung signifikant
  • Konvention: snake_case oder UPPER_CASE fuer 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
  • export macht Variablen an Kind-Prozesse sichtbar, local in Funktionen
  • Indizierte und assoziative Arrays (declare -A)
  • Arithmetik mit $((...)), nur Ganzzahlen
  • Immer "$@" zum Iterieren ueber Argumente

Im naechsten Kapitel: Kontrollstrukturen und Tests.

Zurรผck zum Bash Kurs