Bash Data Structures: Arrays (Artikel 248)
Tiefgehende Analyse von Datenstrukturen in Bash. Erfahren Sie alles über indizierte und assoziative Arrays, deren Manipulation und den Einsatz für komplexe Datenverarbeitung.
# Bash Arrays: Komplexe Datenmengen sicher verarbeiten
TL;DR / Management Summary Wer komplexe Automatisierung schreibt, muss Daten organisieren. Bash Arrays sind das Werkzeug dafür. Seit Bash 4.0 stehen uns neben den klassischen Indizierten Arrays (Listen) auch Assoziative Arrays (Key-Value Maps) zur Verfügung. Wer diese beherrscht, kann Server-Inventare, Konfigurations-Mappings und Status-Listen direkt in der Shell verwalten, ohne auf Python ausweichen zu müssen.
# 1. Einführung & Architektur
Listen und Maps.
Bash speichert Arrays im RAM. Es gibt zwei Typen:
- Indiziert: Zugriff über eine Nummer (
0, 1, 2...). - Assoziativ: Zugriff über einen Namen (String-Key).
# Der Daten-Fluss (Mermaid)
graph TD
A[Data Source: API / File] --> B{Parser}
B -->|Index List| C[Indexed Array: SERVERS]
B -->|Key-Value| D[Associative Array: CONFIG]
C --> E[Loop: Processing]
D --> E
E --> F[Result: Multi-Host Action]
# 2. Indizierte Arrays (Listen)
Elemente sammeln.
# Erstellung und Zugriff
# Deklaration
declare -a NODES=("pve01" "pve02" "pve03")
# Element hinzufügen
NODES+=("pve04")
# Alle Elemente ausgeben (WICHTIG: Quotes!)
echo "${NODES[@]}"
# Länge des Arrays
echo "${#NODES[@]}"
# Slicing (Teilmengen)
# Zeige Elemente ab Index 1 (Länge 2)
echo "${NODES[@]:1:2}"
# 3. Assoziative Arrays (Maps)
Key-Value Paare.
Wichtig: Assoziative Arrays müssen explizit mit declare -A deklariert werden.
# Beispiel: Server-Rollen Mapping
declare -A ROLES
ROLES[web01]="Frontend"
ROLES[db01]="Database"
ROLES[mon01]="Monitoring"
# Zugriff via Key
echo "The role of db01 is: ${ROLES[db01]}"
# Über Keys iterieren
for HOST in "${!ROLES[@]}"; do
echo "Host: $HOST, Role: ${ROLES[$HOST]}"
done
# 4. Day-2 Operations: Fortgeschrittene Manipulation
Filtern und Löschen.
# Elemente löschen
unset NODES[1] # Löscht Element an Index 1
unset ROLES[web01] # Löscht Key 'web01'
# String in Array umwandeln (Parsing)
# Zerlege einen CSV-String
IFS=',' read -r -a VALUES <<< "10.0.0.1,10.0.0.2,10.0.0.3"
# 5. Troubleshooting & “War Stories”
Wenn die Klammern fehlen.
# Story 1: “Der Leerzeichen-Tod”
Symptom: Ein Loop über ein Array von Verzeichnisnamen bricht ab, sobald ein Ordner ein Leerzeichen enthält (My Data).
Ursache: Nutzung von ${NODES[*]} statt "${NODES[@]}". Das erste expandiert zu einem einzelnen String, der an Leerzeichen gesplittet wird.
Lösung: Nutzen Sie immer "${ARRAY[@]}". Die doppelten Anführungszeichen sorgen dafür, dass jedes Element als eigenes Wort erhalten bleibt.
# Story 2: “Das leere Array-Problem”
Symptom: Ein Skript mit set -u bricht ab, wenn ein Array leer ist.
Ursache: Der Zugriff auf ${ARRAY[@]} wirft bei set -u einen Fehler, wenn keine Elemente vorhanden sind.
Lösung: Nutzen Sie den Default-Value Trick: for i in ${ARRAY[@]:+"${ARRAY[@]}"}; do .... Dies verhindert den Fehler bei leeren Listen.
# 6. Fazit & Empfehlung
- Bash Version: Prüfen Sie mit
bash --version. Assoziative Arrays brauchen Version 4.0+. (Standard auf SLES/Arch, aber Vorsicht auf uralten Systemen). - Lesbarkeit: Komplexe verschachtelte Arrays sind in Bash extrem unhandlich. Wenn Sie “Arrays in Arrays” brauchen, wechseln Sie zu Python.
- Wahl: Nutzen Sie Arrays für alle Listen, die in Skripten dynamisch wachsen (z.B. Host-Listen aus einem Cloud-Scan).
# Anhang: Cheatsheet
| Aufgabe | Syntax |
|---|---|
| Indiziertes Array | declare -a NAME |
| Assoziatives Array | declare -A NAME |
| Alle Elemente | "${NAME[@]}" |
| Alle Keys | "${!NAME[@]}" |
| Anzahl Elemente | "${#NAME[@]}" |
| Element an Index i | "${NAME[i]}" |
| Array leeren | NAME=() |
| String zu Array | read -a ARRAY <<< "$STRING" |