Bash-Skripte schreiben: Vom ersten Skript zur Automatisierung

Einzelne Befehle im Terminal sind nützlich – aber ihre wahre Stärke entfalten sie, wenn du sie zu wiederverwendbaren Programmen zusammenfügst. Genau das leistet ein Bash-Skript: eine Textdatei voller Befehle, die nacheinander abgearbeitet werden. Damit automatisierst du Backups, richtest Server ein, verarbeitest Dateien im Stapel und sparst dir tägliches Wiederholen derselben Schritte. Dieser Artikel begleitet dich vom allerersten Skript bis zu Schleifen, Funktionen und sauberer Fehlerbehandlung.

Das erste Skript: Shebang und Ausführungsrechte

Ein Bash-Skript ist nichts weiter als eine Textdatei. Üblicherweise endet sie auf .sh, zwingend ist das aber nicht. Die erste Zeile ist besonders wichtig – sie heißt Shebang und teilt dem System mit, welcher Interpreter das Skript ausführen soll:

Ein minimales Skript sieht so aus: In der ersten Zeile steht die Shebang, danach folgt echo "Hallo Welt". Damit du es starten kannst, musst du es ausführbar machen: chmod +x skript.sh. Anschließend startest du es mit ./skript.sh. Der vorangestellte Punkt-Schrägstrich sagt der Shell, dass das Skript im aktuellen Verzeichnis liegt.

Variablen und Eingaben

Variablen speichern Werte zur Wiederverwendung. In Bash setzt du sie ohne Leerzeichen um das Gleichheitszeichen: name="Anna". Beim Auslesen stellst du ein Dollarzeichen voran: echo "Hallo $name". Diese scheinbar kleine Regel ist eine häufige Fehlerquelle – name = "Anna" mit Leerzeichen funktioniert nicht.

Setze Variablen in der Ausgabe stets in doppelte Anführungszeichen. Das verhindert Probleme, wenn ein Wert Leerzeichen enthält. Benutzereingaben liest du mit read ein: read -p "Dein Name: " name zeigt eine Aufforderung und legt die Antwort in der Variablen name ab. Mit der Option -s wird die Eingabe verborgen, etwa für Passwörter.

Argumente entgegennehmen

Skripte werden flexibler, wenn du ihnen beim Aufruf Werte mitgibst. Diese landen in nummerierten Variablen:

Ruft man also ./backup.sh /home /mnt/backup auf, enthält $1 den Pfad /home und $2 das Ziel /mnt/backup. So baust du universelle Werkzeuge, die mit unterschiedlichen Eingaben arbeiten.

Bedingungen: Entscheidungen treffen

Mit if-Abfragen reagiert dein Skript auf unterschiedliche Situationen. Die Syntax wirkt zunächst eigenwillig, weil die Bedingung in eckigen Klammern steht und auf die Leerzeichen darin geachtet werden muss. Typische Tests sind:

Ein praktisches Muster: Prüfe zu Beginn jedes Skripts, ob die erwarteten Argumente überhaupt vorhanden sind. Ist $# kleiner als die benötigte Anzahl, gibst du eine Hilfemeldung aus und beendest das Skript mit exit 1. Der Rückgabewert 0 signalisiert Erfolg, jeder andere Wert einen Fehler – diese Konvention ist überall im Linux-Ökosystem verankert.

Schleifen: Wiederholungen automatisieren

Hier liegt die eigentliche Magie der Automatisierung. Eine for-Schleife arbeitet eine Liste ab. for datei in *.txt; do echo "$datei"; done durchläuft jede Textdatei im Verzeichnis. So konvertierst du Hunderte Bilder, benennst Dateien um oder verarbeitest Logs in einem Rutsch.

Eine while-Schleife läuft, solange eine Bedingung erfüllt ist – ideal zum zeilenweisen Einlesen von Dateien oder für Warteschleifen, die auf ein Ereignis warten. Mit break brichst du eine Schleife vorzeitig ab, mit continue springst du zum nächsten Durchlauf. Achte bei while-Schleifen darauf, dass die Abbruchbedingung tatsächlich irgendwann eintritt, sonst läuft dein Skript endlos.

Funktionen für saubere Struktur

Sobald Skripte wachsen, lohnen sich Funktionen. Sie bündeln wiederkehrende Logik unter einem Namen und machen den Code lesbar. Du definierst eine Funktion mit meine_funktion() { ... } und rufst sie später einfach über ihren Namen auf. Innerhalb der Funktion greifst du genauso auf Argumente per $1, $2 zu wie im Hauptskript. Eine eigene Logging-Funktion, die jede Meldung mit Zeitstempel versieht, ist ein klassisches Beispiel, das du in fast jedem Skript wiederverwenden kannst.

Robuste Skripte: Fehler abfangen

Ein professionelles Skript bricht ab, sobald etwas schiefläuft, statt blind weiterzumachen. Diese Zeile direkt nach der Shebang ist Gold wert: set -euo pipefail. Sie bewirkt drei Dinge gleichzeitig:

Ergänzend gibt dir trap die Möglichkeit, beim Beenden aufzuräumen – etwa temporäre Dateien zu löschen, egal ob das Skript erfolgreich war oder abgestürzt ist. Diese Sorgfalt unterscheidet ein Wegwerf-Skript von einem, dem du auch produktiv vertrauen kannst.

Skripte testen und absichern

Bevor du ein Skript auf wichtige Daten loslässt, teste es mit harmlosen Beispielen. Die Option bash -n skript.sh prüft die Syntax, ohne etwas auszuführen. Noch besser ist das externe Werkzeug ShellCheck, das deinen Code auf typische Fehler und unsichere Konstruktionen analysiert. Es findet Probleme, die man als Anfänger leicht übersieht, etwa fehlende Anführungszeichen um Variablen.

Wenn dein Skript Passwörter oder API-Schlüssel verarbeitet, schreibe diese niemals im Klartext ins Skript. Lade sie aus Umgebungsvariablen oder einer separaten, geschützten Datei. Für die Erzeugung sicherer Zugangsdaten hilft dir unser Passwort-Generator, und weitere praktische Helfer findest du im Webtools-Bereich.

Ein realistisches Einsatzbeispiel

Stell dir ein Backup-Skript vor: Es nimmt einen Quell- und einen Zielpfad als Argumente entgegen, prüft per if, ob beide existieren, erzeugt mit einem Zeitstempel einen eindeutigen Ordnernamen, kopiert die Daten und schreibt am Ende eine Erfolgsmeldung ins Log. Mit einer for-Schleife könnte es zusätzlich alte Backups löschen, die älter als 30 Tage sind. Genau solche Skripte bilden das Rückgrat jeder Serveradministration.

Damit ein solches Skript automatisch läuft, kombinierst du es mit einem Zeitplaner. Klassisch übernimmt das cron, moderner und mit besserer Protokollierung erledigen das systemd-Timer. Mehr dazu findest du in unserem Artikel über systemd-Dienste verwalten. So entsteht aus ein paar Zeilen Bash eine zuverlässige, unbeaufsichtigte Automatisierung.

Fazit

Bash-Scripting ist keine Hexerei, sondern logisches Zusammensetzen vertrauter Bausteine. Wer Variablen, Bedingungen und Schleifen verstanden hat, kann beinahe jede wiederkehrende Aufgabe automatisieren. Beginne mit kleinen, alltäglichen Problemen – einem Skript, das deine Downloads sortiert, oder einem, das ein Verzeichnis sichert. Mit jeder Zeile wächst dein Werkzeugkasten, und irgendwann fragst du dich, warum du jemals Dinge von Hand erledigt hast.