Skip to content
Zurück zu den Lernmaterialien

Modul 13 — Capstone: ein echtes CLI-Projekt

6. September 2026~4 min read
Lektion von 0/ abgeschlossen
Modul 13 — Capstone: ein echtes CLI-Projekt

CLI-Grundlagen: argv, Usage, Exit

Ein Kommandozeilen-Tool liest seine Eingaben aus Argumenten, verarbeitet sie und beendet sich mit einem Exit-Code. env::args() ist der Eingang:

use std::env;

fn main() {
    let argv: Vec<_> = env::args().collect();

    match argv.get(1) {
        Some(name) => println!("Guten Tag, {name}!"),
        None => println!("Usage: guten-tag <name>"),
    }
}

Drei Entscheidungen stecken in diesem Beispiel:

  • argv.get(1) statt argv[1] — der Index-Zugriff paniziert ohne Argument; get liefert eine Option, und der None-Zweig IST die Usage-Ausgabe
  • Usage statt Schweigen — ohne Eingabe zeigt das Tool, was es erwartet
  • Kein panic im Hauptpfad — ein CLI, das bei falscher Eingabe crasht, ist kein Tool, sondern eine Bombe

Später lernst du process::exit(code) kennen — aber erst, wenn du die Fehlermeldung nach stderr gedruckt hast, damit der Erfolgs-Pfad stdout nicht verschmutzt.

Die CLI-Grundschrift

  • argv[0] = Programmname; Eingaben beginnen bei Index 1
  • get() statt Index-Zugriff: keine Panics bei fehlenden Argumenten
  • Eine Usage-Zeile bei falscher oder fehlender Eingabe
  • Fehlertext nach stderr (eprintln!), Ergebnis nach stdout

📝 Schnellprüfung

Warum argv.get(1) statt argv[1] für den Namen?

Übung: Argumente parsen

🧩 Übung m13-l1-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

Haken setzen, um deinen Lernfortschritt zu markieren:

    Lektion von 0/ abgeschlossen
    Modul 13 — Capstone: ein echtes CLI-Projekt

    Dateien: laden, bearbeiten, speichern

    Ein CLI ohne Dateien ist selten nützlich. fs::read_to_string holt eine ganze Datei als String in den Speicher — und gibt dir das Ergebnis als Result, denn Dateizugriff kann scheitern:

    use std::env;
    use std::fs;
    
    fn main() {
        let argv: Vec<_> = env::args().collect();
        let pfad = argv.get(1).map(String::as_str).unwrap_or("notizen.txt");
    
        match fs::read_to_string(pfad) {
            Ok(inhalt) => println!("Zeilen: {}", inhalt.lines().count()),
            Err(fehler) => eprintln!("Konnte '{pfad}' nicht lesen: {fehler}"),
        }
    }
    

    Beachte die drei Bausteine, die Modul 7 ins Spiel bringt:

    • read_to_string liefert Result — der Fehler darf nicht unter den Teppich
    • unwrap_or gibt einen Standard-Pfad ohne Panic aus
    • eprintln schreibt die Fehlermeldung nach stderr — stdout bleibt für echte Ergebnisse reserviert, damit Pipe-Partner sauber arbeiten

    Und weil ein CLI-Nutzer nie dein unpackendes Innere sehen will: Fehler werden zu Meldungen, nicht zu Panics. Das ist die Anwendung von Error Handling auf die echte Welt.

    Datei-Ein/Ausgabe ohne Stolperfallen

    • fs::read_to_string pfad -> Result; match drauf, nie unwrap im Hauptpfad
    • unwrap_or für Defaults statt einer Panik bei leeren Argumenten
    • eprintln für Fehler, println für Ergebnisse — Trennung für Pipes
    • .lines() leiht vom String — keine Kopie, saubere Iteration

    📝 Schnellprüfung

    Was sagt eprintln gegenüber println für einen Fehlerfall aus?

    Übung: Datei laden ohne Panik

    🧩 Übung m13-l2-e1

    🔮 Vorhersage: Was passiert beim Ausführen?

    Editor wird geladen…
    KI-Tutor (sokratisch — keine Komplettlösungen)

    ✅ Wichtige Erkenntnisse

    Haken setzen, um deinen Lernfortschritt zu markieren:

      Lektion von 0/ abgeschlossen
      Modul 13 — Capstone: ein echtes CLI-Projekt

      Verarbeiten: filtern, sortieren, suchen

      Jetzt wird der geladene Text zur Auswertung. Alles, was du in Modul 10 gelernt hast, trifft hier auf die Daten einer Datei:

      fn main() {
          let log = "info start\nerror disk voll\ninfo retry\nerror timeout\n";
          let such = "error";
      
          let mut treffer: Vec<&str> = log
              .lines()
              .filter(|z| z.contains(such))
              .collect();
          treffer.sort();
      
          for zeile in treffer {
              println!("{zeile}");
          }
      }
      

      Drei Fähigkeiten bisher, eine dritte dazu:

      • lines() leiht Zeilen aus dem String — kein Kopieren, Modul 13 L2
      • filter + collect bauen die Pipeline — Modul 10
      • sort() — und hier verlangt das Sortieren einen kurzen Halt: Die Iterator-Kette reicht NICHT; du brauchst eine echte Vec, weil sortieren einen wahlfreien Zugriff auf die Elemente braucht

      Die gesammelten Zeilen sind geliehene Slices aus dem String — sie leben so lange wie der String. Da treffer im selben Scope bleibt, ist das sicher und der Borrow-Checker nickt.

      Für ein echtes Tool wird daraus eine Suche: suche:server zeigt nur Zeilen mit "server". Die Funktion suche aus den Modul-Codes macht genau das — filter, collect, fertig.

      Datenfluss im CLI

      • lines() leiht; die Vec geliehener Zeilen lebt mit dem String
      • zum Sortieren brauchst du eine geordnete Sammlung, keine Iterator
      • filter wählt Mengen aus, sort ordnet sie, collect bündelt beides
      • Liste der Treffer: Teilmengen-Auswahl und Ordnung in wenigen Zeilen

      📝 Schnellprüfung

      Warum reicht eine Iterator-Kette zum Sortieren nicht aus?

      Übung: Suchen & Sortieren

      🧩 Übung m13-l3-e1

      🔮 Vorhersage: Was passiert beim Ausführen?

      Editor wird geladen…
      KI-Tutor (sokratisch — keine Komplettlösungen)

      ✅ Wichtige Erkenntnisse

      Haken setzen, um deinen Lernfortschritt zu markieren:

        Lektion von 0/ abgeschlossen
        Modul 13 — Capstone: ein echtes CLI-Projekt

        Das fertige Projekt & der Ausblick

        Ein CLI lebt von klarer Struktur. Die bewährte Einteilung:

        • Parsen — Argumente zu Befehlen machen (Modul 13 L1)
        • Verarbeiten — Befehle auf den Zustand anwenden (Modul 13 L3)
        • Ausgeben — das Ergebnis rendern (stdout)

        Im Code des Capstones heißt das: parse_befehl übersetzt ein Argument in einen Befehl der Todo-Welt — neu:TEXT hängt an, zeige zeigt alle, suche:TEXT filtert. Der Zustand ist eine Vec von Notizen; jede Zeile wird über eine Funktion gerendert, die einen Haken setzt oder nicht.

        Warum diese Dreiteilung? Testbarkeit. Jede Stufe ist eine reine Funktion: Argumente rein, Befehle raus — Befehle rein, Zustand raus — Zustand rein, Text raus. Du kannst sie einzeln testen, ohne je ein Programm zu starten. Genau das macht die Übung deutlich.

        🏢 Praxis-Szenario: Das Todo-Tool, das niemand mehr crashen sieht

        Dein Team pflegt einen Notizzettel in einer Textdatei. Drei Kollegen haben eigene Mini-Skripte geschrieben — jedes crasht anders: der eine mit panic bei fehlender Datei, der andere gibt Fehler in die Ausgabepipeline aus, der dritte sortiert nie. Die Anforderung ist die eigene Lebensqualität: EIN Tool, das Argumente versteht, Dateien lädt, filtert und sortiert — ohne je zu explodieren.

        🧩 Übung m13-l4-e1

        🔮 Vorhersage: Was passiert beim Ausführen?

        Editor wird geladen…
        KI-Tutor (sokratisch — keine Komplettlösungen)

        Was du aus dem Kurs mitnimmst

        • Ownership, Borrowing und Lifetimes als Fundament — du weisst JETZT, warum Regeln existieren
        • Fehler sind Werte: Result, ?, eigene Fehlertypen statt Panics
        • Daten fliessen als Pipelines: Iteratoren, Option, keiner Zwischen-Kopie
        • Teamwork: Threads, Channels, Mutex — und wann man sie nicht braucht
        • Ein komplettes CLI-Projekt: strukturiert, testbar, ohne Wegwerf-Code

        ✅ Wichtige Erkenntnisse

        Haken setzen, um deinen Lernfortschritt zu markieren:

          Modul-Checkpoint

          Checkpoint: Modul 13

          Bestehensgrenze: 80 %. Der Versuch wird bewertet und zählt für das Modul-Gate.

          Bereit, dein Wissen zu testen?

          Probiere unsere Übungsprüfungen mit Hunderten von realistischen Fragen aus.

          Üben starten →

          This site uses essential cookies for Stripe payments. No tracking cookies.