Bash-Skripte automatisieren wiederkehrende Aufgaben und sind unverzichtbar für die Server-Administration. Diese Anleitung zeigt die Grundlagen.

Das erste Skript

Erstellen Sie eine Datei hello.sh:

#!/bin/bash
echo "Hallo Welt!"

Die erste Zeile (#!/bin/bash) ist der Shebang - er gibt an, welcher Interpreter das Skript ausführt.

Skript ausführbar machen

chmod +x hello.sh

Skript ausführen

./hello.sh
# oder
bash hello.sh

Variablen

Variablen definieren

#!/bin/bash
NAME="Max"
ALTER=30
VERZEICHNIS="/var/www"

echo "Hallo $NAME"
echo "Du bist $ALTER Jahre alt"

Wichtig: Keine Leerzeichen um das =!

Variablen mit Befehlsausgabe

DATUM=$(date +%Y-%m-%d)
HOSTNAME=$(hostname)
DATEIEN=$(ls -1 | wc -l)

echo "Datum: $DATUM"
echo "Host: $HOSTNAME"
echo "Anzahl Dateien: $DATEIEN"

Spezielle Variablen

| Variable | Bedeutung | |----------|-----------| | $0 | Name des Skripts | | $1, $2, ... | Argumente | | $# | Anzahl Argumente | | $@ | Alle Argumente | | $? | Exit-Code des letzten Befehls | | $$ | Prozess-ID des Skripts |

#!/bin/bash
echo "Skript: $0"
echo "Erstes Argument: $1"
echo "Alle Argumente: $@"
echo "Anzahl: $#"

Benutzereingabe

#!/bin/bash
echo "Wie heißt du?"
read NAME
echo "Hallo $NAME!"

# Einzeiler mit Prompt
read -p "Dein Alter: " ALTER
echo "Du bist $ALTER Jahre alt"

# Passwort (keine Anzeige)
read -sp "Passwort: " PASSWORT
echo ""

Bedingte Ausführung (if)

Syntax

if [ Bedingung ]; then
    # Befehle
elif [ andere Bedingung ]; then
    # Befehle
else
    # Befehle
fi

String-Vergleiche

#!/bin/bash
NAME="admin"

if [ "$NAME" = "admin" ]; then
    echo "Willkommen, Admin!"
elif [ "$NAME" = "gast" ]; then
    echo "Willkommen, Gast!"
else
    echo "Unbekannter Benutzer"
fi

| Operator | Bedeutung | |----------|-----------| | = | Gleich | | != | Ungleich | | -z | String ist leer | | -n | String ist nicht leer |

Zahlen-Vergleiche

#!/bin/bash
ZAHL=10

if [ $ZAHL -gt 5 ]; then
    echo "Größer als 5"
fi

| Operator | Bedeutung | |----------|-----------| | -eq | Gleich (equal) | | -ne | Ungleich (not equal) | | -gt | Größer (greater than) | | -lt | Kleiner (less than) | | -ge | Größer oder gleich | | -le | Kleiner oder gleich |

Datei-Tests

#!/bin/bash
DATEI="/etc/passwd"

if [ -f "$DATEI" ]; then
    echo "Datei existiert"
fi

if [ -d "/var/www" ]; then
    echo "Verzeichnis existiert"
fi

| Operator | Bedeutung | |----------|-----------| | -f | Ist eine Datei | | -d | Ist ein Verzeichnis | | -e | Existiert | | -r | Ist lesbar | | -w | Ist schreibbar | | -x | Ist ausführbar | | -s | Datei ist nicht leer |

Schleifen

for-Schleife

#!/bin/bash

# Über Liste iterieren
for NAME in Max Anna Tom; do
    echo "Hallo $NAME"
done

# Über Dateien iterieren
for DATEI in /var/log/*.log; do
    echo "Verarbeite: $DATEI"
done

# Zahlenbereich
for i in {1..5}; do
    echo "Durchlauf $i"
done

# C-Style
for ((i=0; i<5; i++)); do
    echo "Index: $i"
done

while-Schleife

#!/bin/bash
ZAEHLER=1

while [ $ZAEHLER -le 5 ]; do
    echo "Zähler: $ZAEHLER"
    ((ZAEHLER++))
done

Datei zeilenweise lesen

#!/bin/bash
while read ZEILE; do
    echo "Zeile: $ZEILE"
done < /etc/hosts

Funktionen

#!/bin/bash

# Funktion definieren
sag_hallo() {
    echo "Hallo $1!"
}

# Funktion mit Rückgabewert
addiere() {
    local ERGEBNIS=$(($1 + $2))
    echo $ERGEBNIS
}

# Aufrufen
sag_hallo "Max"

SUMME=$(addiere 5 3)
echo "Summe: $SUMME"

Praktische Beispiele

Backup-Skript

#!/bin/bash
QUELLE="/var/www"
ZIEL="/backup"
DATUM=$(date +%Y%m%d_%H%M%S)
ARCHIV="$ZIEL/backup_$DATUM.tar.gz"

# Prüfen ob Quellverzeichnis existiert
if [ ! -d "$QUELLE" ]; then
    echo "Fehler: $QUELLE existiert nicht"
    exit 1
fi

# Backup erstellen
tar -czf "$ARCHIV" "$QUELLE"

if [ $? -eq 0 ]; then
    echo "Backup erstellt: $ARCHIV"
else
    echo "Fehler beim Backup!"
    exit 1
fi

Service-Überwachung

#!/bin/bash
SERVICE="nginx"

if systemctl is-active --quiet $SERVICE; then
    echo "$SERVICE läuft"
else
    echo "$SERVICE ist gestoppt - starte neu..."
    systemctl start $SERVICE
fi

Festplattenplatz prüfen

#!/bin/bash
GRENZE=80

NUTZUNG=$(df / | tail -1 | awk '{print $5}' | tr -d '%')

if [ $NUTZUNG -gt $GRENZE ]; then
    echo "WARNUNG: Festplatte zu $NUTZUNG% belegt!"
fi

Log-Rotation

#!/bin/bash
LOG_DIR="/var/log/myapp"
MAX_ALTER=7

# Alte Logs löschen
find "$LOG_DIR" -name "*.log" -mtime +$MAX_ALTER -delete

echo "Logs älter als $MAX_ALTER Tage gelöscht"

Exit-Codes

#!/bin/bash

# Erfolg
exit 0

# Fehler
exit 1

Exit-Codes prüfen:

./skript.sh
if [ $? -eq 0 ]; then
    echo "Skript erfolgreich"
else
    echo "Skript fehlgeschlagen"
fi

Fehlerbehandlung

#!/bin/bash

# Bei Fehler abbrechen
set -e

# Undefinierte Variablen als Fehler
set -u

# Pipe-Fehler erkennen
set -o pipefail

# Alle drei kombiniert (empfohlen)
set -euo pipefail

Debugging

# Befehle anzeigen während der Ausführung
bash -x skript.sh

# Im Skript aktivieren
set -x    # Debug an
set +x    # Debug aus

Best Practices

1. Immer Shebang: #!/bin/bash am Anfang 2. Variablen quoten: "$VARIABLE" statt $VARIABLE 3. Exit-Codes nutzen: Bei Fehlern mit exit 1 beenden 4. Kommentare schreiben: Was und warum, nicht wie 5. Fehlerbehandlung: set -euo pipefail 6. Funktionen nutzen: Wiederverwendbarer Code

Fazit

Bash-Skripte sind mächtig für Automation. Starten Sie mit einfachen Skripten und erweitern Sie schrittweise. Die Kombination aus Variablen, Bedingungen, Schleifen und Funktionen ermöglicht komplexe Automatisierungen.