---
id: 2024-10-22-bash-grundkurs-erstelle-dein-erstes-bash-shell-skript
slug: bash-grundkurs-erstelle-dein-erstes-bash-shell-skript
title: "Bash Grundkurs #1: Erstelle Dein Erstes Bash-Shell-Skript"
excerpt: "Willkommen zum ersten Teil unserer Bash-Grundkurs-Serie! Lerne Schritt für Schritt, wie du dein erstes Bash-Shell-Skript erstellst, ausführst, Berechtigungen vergibst und robuste Skripte schreibst."
date: "2024-10-22T09:00:00+01:00"
updated: "2024-11-10T09:00:00+01:00"
author:
  name: "Sebastian Palencsár"
  handle: "spalencsar"
category: "bash-grundlagen"
tags: ["bash", "linux", "shell", "skripting", "cli", "grundkurs"]
reading_time: 15
toc: true
---

**Willkommen zum ersten Teil unserer technischen Serie über Linux und Bash-Programmierung!**

In dieser mehrteiligen Reihe lernst du Schritt für Schritt, wie du deine eigenen Shell-Skripte erstellst, ausführst und zur Automatisierung administrativer Workflows einsetzt. Egal, ob du neu in der Linux-Kommandozeile bist oder deine praktischen Kenntnisse auffrischen und vertiefen möchtest: Dieser Grundkurs vermittelt dir das fundamentale Wissen für sauberes, sicheres und reproduzierbares Skripting.

### Was bedeutet Bash?

Die **Bash** (*Bourne Again Shell*) ist die Standard-Shell in den allermeisten Linux-Distributionen und vielen Unix-Umgebungen. Sie fungiert einerseits als interaktiver Befehlszeilenprozessor zur Steuerung des Systems, andererseits als vollwertige, mächtige Skriptsprache. Mit Bash-Skripten kannst du komplexe Abläufe automatisieren, Systemdienste überwachen, Datensicherungen erstellen und deine Produktivität als Administrator oder Entwickler erheblich steigern.

<span class="nb-accent">In dieser ersten Lektion konzentrieren wir uns auf die absoluten Grundlagen:</span>

Wir erstellen dein allererstes Skript, analysieren den Shebang-Mechanismus, vergeben Ausführungsberechtigungen, unterscheiden verschiedene Ausführungskontexte und verwandeln ein einfaches Skript in ein robustes Programm mit dem **Bash Strict Mode**.

## Der Kursüberblick: Deine Lern-Roadmap

Unser Bash-Grundkurs ist modular aufgebaut und führt dich schrittweise vom ersten Befehl bis hin zu professionellen Automatisierungs-Skripten:

```markdown
┌─────────────────────────────────────────────────────────────┐
│                 BASH GRUNDKURS: LEHRPLAN-ROADMAP            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [ MODUL 1: Erstes Skript & Grundlagen (DIESER ARTIKEL) ]   │
│  └── Shebang, chmod, Subshell vs. Sourcing, Strict Mode     │
│                                                             │
│  [ MODUL 2: Variablen & Datentypen ]                        │
│  └── Strings, Zahlen, Arrays, Quoting & Expansion           │
│                                                             │
│  [ MODUL 3: Kontrollstrukturen & Bedingungen ]              │
│  └── if/then/else, case, Test-Operatoren [[ ]], while, for  │
│                                                             │
│  [ MODUL 4: Funktionen & Modularisierung ]                  │
│  └── Wiederverwendbarkeit, Return-Codes, Scopes (local)     │
│                                                             │
│  [ MODUL 5: Ein- und Ausgabe & Datenströme ]                │
│  └── stdin, stdout, stderr, Pipes, Here-Docs, read-Dialoge  │
│                                                             │
│  [ MODUL 6: Fehlerbehandlung & Debugging ]                  │
│  └── Trap-Signalverarbeitung, Exit-Codes, Logging, xtrace   │
│                                                             │
│  [ MODUL 7: Fortgeschrittene Techniken & Best Practices ]   │
│  └── ShellCheck, Performance, Parsing, Deployment-Skripte   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

<blockquote class="infobox infobox--info">
💡 **Voraussetzungen:** Ein funktionierendes Linux-Terminal (z. B. unter Ubuntu, Debian, Arch Linux, Fedora oder openSUSE) und ein einfacher Texteditor wie `nano` oder `vim`.
</blockquote>

## Schritt 1: Das klassische „Hello World“-Skript erstellen

Lass uns mit dem bewährten „Hello World“-Beispiel starten. Dieses Skript hilft dir, die grundlegende Struktur einer Skriptdatei zu verstehen.

### Terminal öffnen und Skriptverzeichnis anlegen

Öffne ein Terminal-Fenster (unter den meisten Desktop-Umgebungen mit der Tastenkombination `Strg + Alt + T`).

Erstelle einen dedizierten Ordner für deine Skripte und wechsle hinein:

```bash
mkdir -p ~/scripts && cd ~/scripts
```

### Datei im Editor anlegen

Öffne eine neue Datei namens `hello_world.sh` im Texteditor `nano`:

```bash
nano hello_world.sh
```

Gib den folgenden Inhalt ein:

```bash
#!/bin/bash
echo "Hello, World!"
```

**Lass uns diese beiden Zeilen genauer betrachten:**
* **Zeile 1 (`#!/bin/bash`):** Wird als **Shebang** bezeichnet. Sie teilt dem Linux-Betriebssystem mit, welcher Interpreter zur Ausführung der Datei verwendet werden soll.
* **Zeile 2 (`echo "Hello, World!"`):** Der Befehl `echo` gibt die angegebene Zeichenkette auf dem Standard-Ausgabestrom (*stdout*) im Terminal aus.

Speichere die Datei in `nano` mit `Strg + O`, bestätige mit `Enter` und verlasse den Editor mit `Strg + X`.

## Die Architektur hinter dem Shebang (`#!`)

Wenn du eine Binärdatei aufrufst, lädt der Linux-Kernel den Maschinencode direkt. Ein Skript hingegen besteht aus unformatiertem Text.

Damit das System weiß, welches Programm diesen Text verarbeiten soll, prüft der Kernel beim System-Call `execve()` die ersten beiden Bytes der Datei:

```markdown
┌─────────────────────────────────────────────────────────────┐
│                 KERNEL SKRIPT-AUSFÜHRUNGSABLAUF             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [ Benutzer führt Skript aus: ./hello_world.sh ]            │
│         │                                                   │
│         ▼                                                   │
│  Kernel System-Call: execve("./hello_world.sh", ...)        │
│         │                                                   │
│         ▼                                                   │
│  Prüfe die ersten 2 Bytes der Datei (Magic Bytes):          │
│  0x23 0x21  ──>  ASCII-Zeichen: "#!" (Shebang)              │
│         │                                                   │
│         ├── JA: Lese Rest der 1. Zeile (Interpreter-Pfad)   │
│         │   └─► Starte: /bin/bash ./hello_world.sh          │
│         │                                                   │
│         └── NEIN:                                           │
│             └─► Fallback: Starte mit Standard-System-Shell  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### Portabler Shebang: `#!/usr/bin/env bash`

Neben dem klassischen Pfad `#!/bin/bash` existiert eine noch flexiblere Variante:

```bash
#!/usr/bin/env bash
```

Das Hilfswerkzeug `env` sucht die Bash dynamisch anhand der Umgebungsvariable `$PATH` des Benutzers. Das ist besonders nützlich auf Systemen, auf denen die Bash nicht unter `/bin/bash` liegt (wie macOS oder FreeBSD).

## Dateiberechtigungen: Das Skript ausführbar machen

Standardmäßig besitzen neu erstellte Textdateien unter Linux keine Ausführungsrechte (*Execute-Bit*). Wenn du versuchst, das Skript direkt zu starten, verweigert das System den Zugriff:

```bash
./hello_world.sh
# Ausgabe: bash: ./hello_world.sh: Keine Berechtigung (Permission denied)
```

Mit dem Befehl `chmod` fügst du das Ausführungsrecht (`+x`) für die Datei hinzu:

```bash
chmod +x hello_world.sh
```

Jetzt führst du das Skript aus, indem du seinen Namen mit vorangestelltem `./` eingibst:

```bash
./hello_world.sh
```

**Ausgabe:**
```bash
Hello, World!
```

<blockquote class="infobox infobox--info">
💡 **Hinweis zum Pfad `./`:** Aus Sicherheitsgründen durchsucht Linux standardmäßig nur die im `$PATH` hinterlegten Systemverzeichnisse (wie `/usr/bin`), nicht aber das aktuelle Verzeichnis (`.`). Das verhindert, dass bösartige Skripte im aktuellen Ordner unabsichtlich ausgeführt werden. Mit `./` sagst du der Shell explizit: *„Führe die Datei genau hier im aktuellen Verzeichnis aus.“*
</blockquote>

Ausführliche Hintergründe zum Linux-Rechtesystem findest du in unserem Leitfaden zu [chmod und Dateiberechtigungen](/de/linux-neulinge/basics-bis-best-practices-alles-ueber-chmod-in-linux){.badge-link-text}.

## Ausführungsmethoden: Subshell vs. Interpreter vs. Sourcing

Es gibt drei grundlegende Wege, ein Shell-Skript unter Linux auszuführen:

```markdown
┌─────────────────────────────────────────────────────────────┐
│                 DREI METHODEN ZUR SKRIPT-AUSFÜHRUNG         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Methode 1: Direkte Ausführung (./hello_world.sh)           │
│  ├── Benötigt: Read-Bit (r) UND Execute-Bit (x)             │
│  └── Startet: Eigenen isolierten Kindprozess (Subshell)     │
│                                                             │
│  Methode 2: Über Interpreter (bash hello_world.sh)          │
│  ├── Benötigt: Nur Read-Bit (r)                             │
│  └── Startet: Eigenen isolierten Kindprozess (Subshell)     │
│                                                             │
│  Methode 3: Sourcing (source skript.sh oder . skript.sh)    │
│  ├── Benötigt: Nur Read-Bit (r)                             │
│  └── Startet: KEINE Subshell! Läuft in der AKTUELLEN Shell  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### 1. Direkte Ausführung (`./hello_world.sh`)
Der Standardweg für fertige Skripte. Startet eine neue Kind-Shell (*Subshell*). Benötigt `chmod +x`.

### 2. Aufruf über den Interpreter (`bash hello_world.sh`)
Du übergibst die Datei direkt an die Bash:
```bash
bash hello_world.sh
```
* **Vorteil:** Die Datei benötigt kein Execute-Bit (`chmod +x`), sondern lediglich Leserechte (`r`), da die Bash die Datei als reine Textdatei liest.
* **Einsatz:** Ideal zum schnellen Testen während der Entwicklung.

### 3. Einlesen in die aktuelle Shell (`source` oder `.`)
Beim *Sourcen* wird kein neuer Prozess gestartet:
```bash
source hello_world.sh
# oder kurz:
. hello_world.sh
```
* **Wirkung:** Variablen und Funktionen, die im Skript definiert werden, bleiben nach Ablauf direkt in deiner aktuellen Terminal-Sitzung verfügbar (wird z. B. für `source ~/.bashrc` genutzt).

## Vom einfachen Shell-Skript zum echten Bash-Skript

Bisher haben wir nur einfache Kommandos ausgeführt. Um das volle Potenzial der Bash zu nutzen und fortgeschrittene Sprachfeatures sowie Schutzmechanismen einzubinden, erweitern wir unser Skript:

Öffne `hello_world.sh` erneut im Editor:

```bash
nano hello_world.sh
```

Ersetze den Inhalt durch folgenden Code:

```bash
#!/usr/bin/env bash

# Bash Strict Mode aktivieren
set -euo pipefail
IFS=$'\n\t'

# 1. Variable deklarieren
greeting="Hello, World!"

# 2. Parameter-Expansion: String in Großbuchstaben umwandeln
uppercase_greeting="${greeting^^}"

# 3. Farbige Ausgabe mit ANSI-Escape-Sequenzen
echo -e "\e[1;34m$greeting\e[0m"
echo -e "\e[1;31m$uppercase_greeting\e[0m"

# 4. Bash-spezifische Bedingung und Mustervergleich
if [[ "$greeting" == *"World"* ]]; then
    echo "Die Begrüßung enthält das Wort 'World'."
fi
```

### Was bedeuten diese Neuerungen im Detail?

1. **`set -euo pipefail` (Bash Strict Mode):**
   * `set -e` (*errexit*): Bricht das Skript sofort ab, wenn ein Befehl fehlschlägt.
   * `set -u` (*nounset*): Verhindert die Ausführung bei Tippfehlern in Variablennamen.
   * `set -o pipefail`: Erkennt Fehler auch innerhalb von Pipeline-Befehlen.
2. **`IFS=$'\n\t'`:** Verhindert Worttrennung bei Leerzeichen in Dateinamen.
3. **`${greeting^^}`:** Bash-spezifische Parameter-Expansion, die den Text in Großbuchstaben konvertiert.
4. **`echo -e "\e[1;34m..."`:** Aktiviert ANSI-Farbcodes (Blau und Rot) im Terminal.
5. **`[[ "$greeting" == *"World"* ]]`:** Der moderne Bash-Bedingungsoperator `[[ ]]` ermöglicht flexiblen Mustervergleich mit Wildcards.

Speichere die Änderungen und führe das Skript erneut aus:

```bash
./hello_world.sh
```

Du siehst nun eine farbige Ausgabe und die Bestätigung der Bedingungsprüfung im Terminal.

## Exit-Codes & Rückgabewerte (`$?`)

Jedes saubere Skript gibt dem aufrufenden System einen Exit-Code zurück:
* `exit 0`: Signale an das Betriebssystem: **Erfolg** (*Success*).
* `exit 1` bis `exit 255`: Signalisiert einen **Fehlerzustand**.

```bash
#!/usr/bin/env bash
set -euo pipefail

echo "Systemprüfung läuft..."

# Erfolgreicher Abschluss
exit 0
```

Den Exit-Code des zuletzt ausgeführten Befehls oder Skripts kannst du mit `echo $?` abfragen:

```bash
./hello_world.sh
echo "Status: $?"  # Gibt 0 aus
```

## Debugging: Fehler in Skripten schnell finden

Wenn ein Skript nicht wie erwartet funktioniert, bietet die Bash eingebaute Diagnose-Optionen:

### 1. Ausführungs-Trace (`bash -x`)

Mit `-x` (*xtrace*) zeigt die Bash jeden ausgeführten Befehl mitsamt allen aufgelösten Variablen an:

```bash
bash -x hello_world.sh
```

### 2. Syntax-Prüfung (`bash -n`)

Prüft die Datei rein auf Syntaxfehler (wie vergessene Anführungszeichen), ohne Befehle auszuführen:

```bash
bash -n hello_world.sh
```

### 3. Statische Code-Analyse mit ShellCheck

Das Open-Source-Tool **ShellCheck** erkennt typische Fehler und schlechte Gewohnheiten:

```bash
# Installation unter Ubuntu/Debian
sudo apt install shellcheck

# Analyse durchführen
shellcheck hello_world.sh
```

## Übungen & Praxis-Check

<blockquote class="infobox infobox--practice">
❗ **Praxisaufgaben zur Lektion #1:**

1. **Aufgabe 1 (Interaktiver Dialog):**  
   Schreibe ein Skript `dialog.sh`, das den Benutzer mit `read -r` nach seinem Namen fragt und eine personalisierte, farbige Begrüßung ausgibt.
2. **Aufgabe 2 (Systemstatus-Report):**  
   Erstelle ein Skript `status.sh`, das den aktuellen Benutzer (`$USER`), das Datum, den Hostnamen und den aktuellen Verzeichnispfad (`pwd`) strukturiert anzeigt.
3. **Aufgabe 3 (Strict Mode Test):**  
   Erstelle ein Skript mit `set -u` und versuche, eine nicht definierte Variable auszugeben. Beobachte die Fehlermeldung der Bash.
</blockquote>

### Musterlösung zu Aufgabe 1:

```bash
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

# Frage nach dem Namen
echo -n "Wie heißt du? "
read -r name

# Personalisierte Begrüßung
greeting="Hallo, $name!"
echo -e "\e[1;32m$greeting\e[0m Willkommen zum Bash-Grundkurs."

exit 0
```

## Befehlsreferenz (Cheatsheet)

| Befehl / Syntax | Funktion & Beschreibung |
|---|---|
| `#!/usr/bin/env bash` | Portabler Shebang: Sucht Bash dynamisch über `$PATH` |
| `chmod +x skript.sh` | Macht die Skriptdatei für den Benutzer ausführbar |
| `./skript.sh` | Führt das Skript in einer isolierten Subshell aus |
| `bash skript.sh` | Führt das Skript über den Interpreter aus (benötigt nur Leserechte) |
| `source skript.sh` | Liest das Skript direkt in die aktuelle Shell ein |
| `set -euo pipefail` | Aktiviert den Bash Strict Mode für maximale Robustheit |
| `echo "$?"` | Zeigt den Exit-Code des zuletzt beendeten Programms |
| `bash -x skript.sh` | Startet das Skript im interaktiven Trace-Modus zur Fehlersuche |
| `bash -n skript.sh` | Prüft die Syntax der Skriptdatei ohne Ausführung |

## Weiterführende Ressourcen

| Ressource | Beschreibung |
|---|---|
| [GNU Bash Reference Manual](https://www.gnu.org/software/bash/manual/){.badge-link-text} | Die offizielle Dokumentation des GNU-Projekts |
| [ShellCheck Tool](https://www.shellcheck.net/){.badge-link-text} | Online-Linter und Sicherheitsprüfer für Shell-Skripte |
| [Linux Befehlszeilenprozessor Leitfaden](/de/linux-neulinge/befehlszeilenprozessor-in-linux){.badge-link-text} | Ausführliche Grundlagen zur Shell-Architektur |
| [chmod & Dateiberechtigungen](/de/linux-neulinge/basics-bis-best-practices-alles-ueber-chmod-in-linux){.badge-link-text} | Detaillierte Rechteverwaltung unter Linux |

## Fazit

Mit dem Erstellen deines ersten Bash-Skripts, dem Verständnis für Shebang und Dateiberechtigungen sowie der Absicherung durch den Bash Strict Mode hast du das Fundament für alle weiteren Schritte in der Linux-Automatisierung gelegt.

<blockquote class="infobox infobox--info">
💡 **Tipp:** Verwende bei jedem neuen Skript von Beginn an den portablen Shebang `#!/usr/bin/env bash` und aktiviere `set -euo pipefail`. Das verhindert unvorhergesehenes Verhalten und erleichtert die spätere Fehlersuche erheblich.
</blockquote>

In der nächsten Lektion widmen wir uns der dynamischen Datenverarbeitung und schauen uns an, wie Variablen deklariert, manipuliert und in Skripten genutzt werden:  
👉 **Weiter geht es mit:** [Bash Grundkurs #2: Verwendung Von Variablen In Bash](/de/bash-grundlagen/bash-grundkurs-verwendung-von-variablen-in-bash){.badge-link-text}

👉 **Zur Kursübersicht:** [Alle Lektionen des Bash-Grundkurses](/de/category/bash-grundlagen){.badge-link-text}
