Systemadministration & Netzwerk
Bash-Scripting lernen: Alltag automatisieren
Bash-Scripting lernen: du automatisierst Admin-Alltag mit Variablen, Schleifen, Pipes, Fehlerbehandlung und erkennst, wann Python besser passt.
KI-generiert Ein paar wiederkehrende Kommandos auf dem Server, und du merkst schnell: Das klickst du nicht mehr per Hand. Bash-Scripting ist dann das naheliegende Werkzeug, um aus Einzelbefehlen robuste, wiederverwendbare Helfer zu bauen. Die Kunst besteht darin, nicht nur irgendetwas hinzuhacken, sondern Skripte zu schreiben, die auch Monate später noch verständlich sind und im Fehlerfall sauber reagieren.
Bash-Skripte sauber starten
Ein Bash-Skript ist im Kern eine Textdatei mit Befehlen, die du sonst in die Shell tippst. Ein minimaler, aber sinnvoller Start:
#!/usr/bin/env bash
set -euo pipefail
echo "Backup läuft..."
Die erste Zeile sagt dem System, welche Shell das Skript interpretieren soll. set -euo pipefail ist so etwas wie der Sicherheitsgurt:
-e: Skript bricht ab, wenn ein Befehl fehlschlägt.-u: Zugriff auf nicht gesetzte Variablen wird als Fehler behandelt.-o pipefail: Pipelines gelten als fehlgeschlagen, wenn ein Teilbefehl fehlschlägt, nicht nur der letzte.
Gerade in Admin-Skripten vermeidest du damit halbfertige Zustände, etwa bei Deployments oder Backups.
Variablen: sauber setzen und zitieren
In Bash gibt es keine Typen im klassischen Sinn. Alles ist String, und du musst mit Anführungszeichen und Substitution sauber umgehen.
Variablen setzen und lesen
NAME="web01"
PORT=8080
echo "Server: $NAME, Port: $PORT"
Wichtig:
- Kein Leerzeichen um das Gleichheitszeichen.
- Beim Lesen immer mit
$davor. - Strings mit Leerzeichen immer in Anführungszeichen:
DIR="/var/www/my app" # korrekt
cd "$DIR" # immer quoten
Das konsequente Quoten schützt dich vor kaputten Pfaden, Leerzeichen und Wildcards, die zu unerwartetem Verhalten führen.
Umgebungsvariablen und Defaults
Für Admin-Skripte ist es praktisch, Konfiguration über Umgebungsvariablen zuzulassen:
BACKUP_DIR="${BACKUP_DIR:-/var/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
echo "Sichere nach: $BACKUP_DIR"
echo "Aufbewahrung: $RETENTION_DAYS Tage"
${VAR:-default} bedeutet: Nutze VAR, falls gesetzt, sonst den Default. So kannst du Skripte flexibel konfigurieren, ohne sie zu ändern.
Bedingungen: if, test und [[ ]]
Mit Bedingungen reagierst du auf Zustände des Systems oder Parameter.
Klassische if-Struktur
if [[ "$EUID" -ne 0 ]]; then
echo "Bitte als root ausführen." >&2
exit 1
fi
Empfehlenswert ist [[ ... ]] statt des alten test beziehungsweise [ ... ], weil es robuster mit Strings und Mustern umgeht.
Häufige Tests:
- Dateien:
-f datei: reguläre Datei existiert-d verzeichnis: Verzeichnis existiert-x datei: Datei ist ausführbar- Strings:
-z "$VAR": leer-n "$VAR": nicht leer- Zahlen:
-eq,-ne,-lt,-le,-gt,-ge
Beispiel: Check eines Konfigurationsverzeichnisses:
CONFIG_DIR="/etc/myapp"
if [[ ! -d "$CONFIG_DIR" ]]; then
echo "Konfigurationsverzeichnis $CONFIG_DIR fehlt." >&2
exit 2
fi
Schleifen: über Listen und Dateien iterieren
Schleifen sind das Herzstück vieler Admin-Skripte, etwa um eine Liste von Hosts oder Dateien abzuarbeiten.
for-Schleife
for host in web01 web02 db01; do
echo "Pinge $host..."
ping -c1 "$host" >/dev/null 2>&1 || echo "$host nicht erreichbar"
done
Statt feste Hostnamen kannst du auch Kommandosubstitution nutzen:
for user in $(cut -d: -f1 /etc/passwd); do
echo "Benutzer: $user"
done
Vorsicht: Diese $(...)-Variante bricht bei Leerzeichen. Für Dateilisten ist eine while-Schleife mit read meist besser.
while read für Dateien und Pipes
while IFS= read -r line; do
echo "Zeile: $line"
done < /var/log/syslog
Wichtig:
IFS=verhindert das Trimmen von führenden/trailing Spaces.-rverhindert, dass Backslashes interpretiert werden.
So kannst du Logdateien auswerten oder Konfigurationsdateien Zeile für Zeile durchgehen, ohne an Sonderzeichen zu scheitern.
Pipes und Filter: die Unix-Philosophie ausnutzen
Bash-Skripte glänzen, wenn du viele kleine Werkzeuge kombinierst. Typischer Admin-Alltag:
journalctl -u nginx.service \
| grep "error" \
| tail -n 50
Oder: Veraltete Logdateien löschen, aber vorher einmal anzeigen:
find /var/log -name "*.log" -mtime +30 \
| tee /tmp/alte-logs.txt \
| xargs -r rm
Erläuterung:
findliefert eine Liste alter Logs.teeschreibt diese Liste in eine Datei und reicht sie gleichzeitig weiter.xargs -r rmlöscht die Dateien, führtrmaber nur aus, wenn es überhaupt Einträge gibt (-r).
Pipes sind ideal, wenn du Datenströme verarbeitest: Logs filtern, Prozesse suchen, Backups durch gzip jagen.
Fehlerbehandlung: nicht nur auf Gutwetter optimieren
Viele Bash-Skripte funktionieren, solange nichts schiefgeht. Professionell wird es, wenn du Fehler erkennst und sauber reagierst.
Exit-Codes prüfen
Jeder Befehl liefert einen Exit-Code, abrufbar über $?. 0 bedeutet Erfolg, alles andere ist ein Fehler.
cp /etc/nginx/nginx.conf /backup/nginx.conf
if [[ $? -ne 0 ]]; then
echo "Backup der nginx.conf fehlgeschlagen." >&2
exit 1
fi
Mit set -e sparst du dir viele dieser Checks, aber bei kritischen Schritten kannst du trotzdem gezielt reagieren.
Eleganter ist es oft, direkt zu prüfen:
if ! cp /etc/nginx/nginx.conf /backup/nginx.conf; then
echo "Backup der nginx.conf fehlgeschlagen." >&2
exit 1
fi
trap für Aufräumarbeiten
Wenn ein Skript abbricht, sollen temporäre Dateien weggeräumt oder Dienste wieder gestartet werden. Das erledigst du mit trap:
TMPFILE="$(mktemp)"
cleanup() {
rm -f "$TMPFILE"
}
trap cleanup EXIT
echo "Arbeite mit $TMPFILE..."
# hier dein Code
Die Funktion cleanup wird bei jedem Skriptende aufgerufen, egal ob erfolgreich oder wegen Fehlers. Du kannst auch gezielt auf Signale reagieren, etwa INT für Strg+C.
Praktische Admin-Skripte: drei typische Beispiele
Statt Theorie ein paar kompakte Muster, die du leicht an deine Umgebung anpassen kannst.
1. Einfaches Log-Rotationsskript
#!/usr/bin/env bash
set -euo pipefail
LOG_DIR="/var/log/myapp"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
find "$LOG_DIR" -name "*.log" -mtime +"$RETENTION_DAYS" \
-print -delete
Dieses Skript löscht alle Logdateien, die älter als eine bestimmte Anzahl von Tagen sind, und gibt sie beim Löschen aus. Du kannst es per Cron einplanen.
2. Service-Check mit Benachrichtigung
#!/usr/bin/env bash
set -euo pipefail
SERVICE="${1:-nginx}"
if ! systemctl is-active --quiet "$SERVICE"; then
echo "Dienst $SERVICE ist nicht aktiv." >&2
# hier z. B. Mail verschicken oder Monitoring triggern
exit 1
fi
echo "Dienst $SERVICE läuft."
So ein Skript kannst du in Monitoring-Checks einbinden oder auf mehreren Servern ausrollen.
3. Einfache Backup-Routine mit Datum
#!/usr/bin/env bash
set -euo pipefail
SRC_DIR="/var/www"
DEST_DIR="/backup"
DATE="$(date +%Y-%m-%d)"
TARGET="$DEST_DIR/www-$DATE.tar.gz"
mkdir -p "$DEST_DIR"
tar -czf "$TARGET" "$SRC_DIR"
echo "Backup erstellt: $TARGET"
Danach ergänzst du Rotationslogik, Checks auf freien Speicherplatz und vielleicht eine Übertragung auf einen anderen Host.
Wann Bash und wann Python?
Bash ist nicht für jede Aufgabe das richtige Werkzeug. Ein paar Leitlinien helfen bei der Entscheidung:
| Situation | Bash geeignet? | Python geeigneter? |
|---|---|---|
| Einfache Kommandoabfolgen | Ja, optimal | Overkill |
Dateisystem-Operationen, rsync, cp | Ja, sehr gut | Nur bei komplexer Logik nötig |
| Komplexe Stringverarbeitung, JSON | Eingeschränkt | Klarer Vorteil |
| API-Calls (HTTP, JSON) | Nur mit Tools wie curl | Ja, sehr gut |
| Längere Geschäftslogik, viele Bedingungen | Unübersichtlich | Besser lesbar und testbar |
| Cross-Plattform (Linux, macOS, Windows) | Problematisch | Mit Einschränkungen gut machbar |
Faustregeln:
- Wenn dein Skript hauptsächlich andere Programme aufruft und Dateien verschiebt, ist Bash fast immer passend.
- Wenn du beginnst, mehr als ein paar Zeilen Stringmanipulation, JSON-P parsing oder komplexe Datenstrukturen zu bauen, wechsle lieber zu Python.
- Ab etwa 150 bis 200 Zeilen Bash lohnt es sich, kritisch zu prüfen, ob die Logik nicht in einer „richtigen“ Programmiersprache besser aufgehoben ist.
Für Admins in München und anderswo ist eine realistische Mischung sinnvoll: kleine Helfer in Bash, komplexere Tools in Python. Beides ergänzt sich gut.
Struktur, Lesbarkeit und Sicherheit
Ein Bash-Skript ist schnell geschrieben, aber schwer zu warten, wenn Struktur und Stil fehlen. Einige einfache Konventionen helfen:
- Kopfbereich:
- Shebang
set -euo pipefail- kurze Beschreibung als Kommentar
- Klare Funktionsnamen:
backup_nginx_config() { ... }
restart_service() { ... }
- Eingaben prüfen:
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <service-name>" >&2
exit 1
fi
- Keine gefährlichen
rm-Aufrufe ohne Pfad-Checks:
if [[ -d "$TARGET_DIR" && "$TARGET_DIR" == /var/www/* ]]; then
rm -rf "$TARGET_DIR"
else
echo "Unsicheres Zielverzeichnis: $TARGET_DIR" >&2
exit 1
fi
So vermeidest du die klassischen „rm -rf /“-Unfälle und andere böse Überraschungen.
Wie du weiter übst
Am besten lernst du Bash-Scripting, indem du reale Aufgaben aus deinem Admin-Alltag automatisierst:
- Ein kleines Inventar-Skript, das Hostname, IPs und installierte Pakete auflistet.
- Ein Deployment-Skript für eine Webanwendung.
- Ein Helfer, der Logdateien auf typische Fehler durchsucht und eine Übersicht erzeugt.
Nimm dir bestehende Einmal-Kommandos aus deiner Shell-History und forme sie zu wiederverwendbaren Skripten. Wenn du das strukturiert und mit Feedback lernen willst, findest du passende Linux- und Scripting-Schulungen bei cmt.de.
Bash ist kein Selbstzweck. Aber als Admin, der seine tägliche Arbeit ernst nimmt, kommst du an soliden Shell-Skripten nicht vorbei. Je früher du dir saubere Muster und Gewohnheiten antrainierst, desto entspannter läuft dein Alltag auf der Kommandozeile.
Nächster Schritt
Passenden Kurs zu Admin & Netzwerk finden.
Feste Termine, erfahrene Trainer, Präsenz in München und Durchführungsgarantie. Buchen kannst du direkt auf cmt.de.