Linux · Tag 1 · Kapitel 11 von 12

Wildcards, Redirection & Echo

Drei Konzepte, die deine Shell vom „Befehl-für-Befehl-Tippen“ zum Werkzeug-Set erheben: Platzhalter für viele Dateien gleichzeitig, Ausgabeumleitung in Dateien und stdin/stdout/stderr verstehen. Lab 1.3 setzt alles zusammen.

📚 Kapitel 11 ⏱️ ca. 25 min Theorie + 45 min Lab 🧪 Lab 1.3
11.1

echo — der einfachste Befehl mit den meisten Tricks

Grundlage

echo gibt einfach Text aus. Klingt banal, ist aber das wichtigste Werkzeug, wenn du Skripte schreibst oder schnell etwas in eine Datei schreiben willst.

bash
# Einfache Ausgabe
echo "Hallo Linux-Welt"

# Mit Variablen — werden ausgewertet (Dollarzeichen)
echo "Mein User: $USER"
echo "Heute ist $(date)"
echo "Mein Home: $HOME"

# Ohne Newline am Ende — nützlich für Prompts
echo -n "Bitte eingeben: "

# Mit Escape-Sequenzen interpretieren (-e)
echo -e "Zeile 1\nZeile 2\nZeile 3"
echo -e "Tab\there\tand\tthere"
echo -e "Rot: \e[31mfehler\e[0m"

Wichtige Escape-Sequenzen mit -e

\nNewline (Zeilenumbruch)
\tTab (Tabulator)
\\Backslash selbst
\bBackspace
\rCarriage Return (Zeilenanfang)
\e[31mANSI: rot · \e[0m = Reset

Single Quotes vs. Double Quotes

bash
# Double Quotes: Variablen werden ausgewertet
echo "User: $USER"
# Ausgabe: User: admin

# Single Quotes: alles wird wörtlich genommen
echo 'User: $USER'
# Ausgabe: User: $USER

# Keine Quotes: funktioniert oft, aber riskant bei Leerzeichen
echo Hallo Welt
💡
Faustregel

Im Zweifel Double Quotes. Sie schützen vor Wortgrenzen (Leerzeichen) und erlauben trotzdem Variablen. Single Quotes nur, wenn du ausdrücklich KEINE Auswertung willst (z.B. ein Beispielcode in der Doku).

11.2

Wildcards / Globbing — viele Dateien auf einmal

Pflicht

Wildcards (auch „Globs“ genannt) sind Platzhalter, die die Shell durch passende Dateinamen ersetzt, bevor sie den Befehl ausführt. Damit kannst du ls *.txt sagen — und die Shell macht intern daraus ls anna.txt bernd.txt clara.txt.

⚙️
Wichtig zu verstehen

Wildcards werden von der Shell aufgelöst, nicht vom Befehl selbst. rm sieht nie das Sternchen — es bekommt schon die fertige Liste der Treffer übergeben. Das hat Konsequenzen: wenn nichts passt, wird das Sternchen wörtlich übergeben, was zu komischen Fehlern führen kann.

Die vier Wildcards

WildcardBedeutungBeispiel
* beliebig viele beliebige Zeichen (auch null) ls *.txt — alle .txt-Dateien
? GENAU EIN beliebiges Zeichen ls test?.txt — test1.txt bis testZ.txt
[abc] EIN Zeichen aus der Liste ls test[135].txt — nur 1, 3, 5
[a-z] / [0-9] EIN Zeichen aus einem Bereich ls report-[a-c].txt
[!abc] EIN Zeichen, das NICHT in der Liste ist ls test[!0].txt — alles außer test0.txt

Praxis-Beispiele

bash
# Alle Dateien, die mit "m" beginnen
ls /usr/bin/m*

# Genau 3-zeichige Befehlsnamen
ls /usr/bin/???

# Alle Konfig-Dateien
ls /etc/*.conf

# Alle Bilder
ls ~/*.jpg ~/*.png ~/*.gif

# Alle Dateien, die mit a, b oder c beginnen
ls [abc]*

# Alle Zahlen-Dateien
ls test[0-9].txt

# Alle versteckten Dateien (mit Punkt am Anfang)
ls -d .*

Brace Expansion — kein Wildcard, aber verwandt

Geschweifte Klammern sind keine Wildcards im engeren Sinn — die Shell erzeugt damit Listen, OHNE auf existierende Dateien zu schauen:

bash
# Zahlen-Range
echo {1..10}
# Ausgabe: 1 2 3 4 5 6 7 8 9 10

# Buchstaben-Range
echo {a..e}
# Ausgabe: a b c d e

# Mit Schrittweite
echo {0..20..5}
# Ausgabe: 0 5 10 15 20

# Listen
echo {anna,bernd,clara}
# Ausgabe: anna bernd clara

# Kombiniert — sehr mächtig!
mkdir -p projekt/{src,tests,docs}/{2024,2025}
# Erzeugt 6 Verzeichnisse in einer Zeile

touch backup_{jan,feb,mar}_{2024,2025}.tar.gz
# Erzeugt 6 Dateien: backup_jan_2024.tar.gz, …

# Klassiker: schnelle Kopie mit Backup
cp /etc/nginx/nginx.conf{,.bak}
# entspricht: cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
🆚
Unterschied Wildcard vs. Brace Expansion

Wildcards (*, ?, []) suchen in existierenden Dateinamen. Brace Expansion ({ }) erzeugt Text-Listen, unabhängig davon, ob die Dateien existieren. touch a{1..3} erzeugt drei NEUE Dateien; ls a* listet EXISTIERENDE.

11.3

stdin, stdout, stderr — die drei Ströme

Konzept

Jeder Linux-Prozess hat drei Standard-Datenkanäle (engl. „streams“). Mit Redirection lenkst du diese um — das ist die Basis von allem, was Linux mächtig macht.

┌───────────┐ ┌──────────────┐ ┌───────────┐ │ stdin │────────>│ Prozess │────────>│ stdout │ │ (0) │ │ │ │ (1) │ │ Eingabe │ │ │────┐ │ Ausgabe │ └───────────┘ └──────────────┘ │ └───────────┘ ▼ ┌───────────┐ │ stderr │ │ (2) │ │ Fehler │ └───────────┘
StreamFD-NummerDefault-ZielWofür?
stdin0TastaturEingabe in den Prozess
stdout1Bildschirmnormale Ausgabe
stderr2BildschirmFehler-Ausgabe

Wichtige Erkenntnis: stdout und stderr sind getrennt. Du siehst beide am Bildschirm, aber du kannst sie unabhängig umleiten.

11.4

Redirection — Ausgaben umleiten

Pflicht

Die wichtigsten Operatoren

OperatorWas er macht
> dateistdout in Datei umleiten (überschreibt!)
>> dateistdout an Datei anhängen
2> dateistderr in Datei umleiten
2>> dateistderr an Datei anhängen
&> dateistdout UND stderr in dieselbe Datei
> datei 2>&1klassische Variante: stdout in Datei, stderr „in stdout“
< dateistdin AUS Datei lesen
<< EOFHere-Doc — mehrzeiliger stdin

Live-Demo

bash
# In eine Datei schreiben (überschreibt!)
ls -la > inhalt.txt
cat inhalt.txt

# An eine Datei ANHÄNGEN
echo "Neuer Eintrag" >> inhalt.txt
date >> inhalt.txt
cat inhalt.txt

# Nur Fehler in Datei
ls /existiert_nicht 2> fehler.log
cat fehler.log

# stdout in eine Datei, stderr in eine andere
ls /etc /existiert_nicht > gut.log 2> fehler.log
cat gut.log
cat fehler.log

# beides in eine Datei (alte Syntax)
ls /etc /existiert_nicht > alles.log 2>&1

# beides in eine Datei (kurze Syntax)
ls /etc /existiert_nicht &> alles.log

# stdin aus Datei
sort < liste.txt

# Here-Doc für mehrzeiligen Inhalt
cat > willkommen.txt << EOF
Hallo!
Willkommen bei HanovaTech.
Heute ist $(date +%F).
EOF
cat willkommen.txt

/dev/null — das schwarze Loch

/dev/null ist eine spezielle Gerätedatei, die alles „verschluckt“ — was du dort reinschreibst, ist weg. Beim Lesen ist sie sofort EOF. Klassische Anwendungen:

bash
# Ausgabe komplett unterdrücken
ls -la /etc > /dev/null

# Nur Fehler unterdrücken, normale Ausgabe behalten
find / -name "*.conf" 2> /dev/null

# Alles unterdrücken (still und leise)
some-command &> /dev/null

# In Skripten, wenn du nur den Exit-Code prüfst
if grep -q "search" datei.txt &> /dev/null; then
    echo "Treffer!"
fi

# Datei leeren ohne löschen
> /var/log/myapp.log
# entspricht: cat /dev/null > /var/log/myapp.log

/dev/zero — endlose Nullen

Gegenstück zu /dev/null: liefert unendlich viele Null-Bytes beim Lesen. Nützlich, um große Test-Dateien zu erzeugen:

bash
# 10-MB-Testdatei
dd if=/dev/zero of=test.bin bs=1M count=10

# 1-GB-Datei (Vorsicht: Disk-Verbrauch!)
dd if=/dev/zero of=gross.bin bs=1M count=1024
11.5

Pipes | — Programme verketten (Vorgriff)

Vorgriff

Eine Pipe (Pipe-Symbol |, deutsche Tastatur: AltGr+<) verbindet stdout eines Programms mit stdin des nächsten. Damit kannst du kleine Werkzeuge zu großen Workflows verknüpfen.

Befehl1 ────stdout─────> Befehl2 ────stdout─────> Bildschirm │ └── via | (Pipe)
bash
# Wie viele Dateien sind in /etc?
ls /etc | wc -l

# Welche Prozesse laufen mit "ssh" im Namen?
ps -ef | grep ssh

# Top 5 RAM-Verbraucher
ps aux --sort=-%mem | head -6

# Eindeutige Shells, die User benutzen
cut -d: -f7 /etc/passwd | sort -u

# Live-Logs mit Filter
sudo tail -f /var/log/secure | grep "Failed password"

Pipes sind das Herz der Unix-Philosophie: kleine Tools, die zusammenarbeiten. Wir vertiefen das an Tag 2.

tee — Strom in zwei Richtungen schicken

tee liest stdin und schreibt es gleichzeitig auf stdout UND in eine Datei. Der Name kommt von „T-Stück“ in der Klempnerei.

bash
# Ausgabe sehen UND in Datei speichern
ls -la /etc | tee inhalt.txt

# An Datei anhängen statt überschreiben
date | tee -a log.txt

# Klassiker: in geschützte Datei schreiben mit sudo
echo "127.0.0.1 testhost" | sudo tee -a /etc/hosts
# Funktioniert, wo "sudo echo >>" scheitert (Redirect läuft ohne sudo)
🧪 Lab 1.3 HanovaTech-Logs erzeugen und sortieren 45 min
📧 E-Mail vom Senior-Admin:
„Im Logs-Ordner ist heute viel los — und ohne Wildcards und Umleitung bekommst du das nie schnell genug aufgeräumt. Üb das jetzt. Wer das nicht kann, ist im Admin-Alltag verloren.“
Teil A — Log-Einträge mit echo und Redirection (10 min)
  1. Wechsle in ~/hanovatech/logs/ (Struktur aus Lab 1.2). Falls noch nicht vorhanden: erst mit mkdir -p anlegen.
  2. Schreibe mit echo die Zeile "Server gestartet um 08:00" in eine neue Datei start.log.
  3. Hänge zwei weitere Zeilen an dieselbe Datei an: "User admin eingeloggt um 08:05" und "Datum: $(date)".
  4. Zeige den Inhalt mit cat.
bash
cd ~/hanovatech/logs/    # falls nicht da: mkdir -p ~/hanovatech/logs/ && cd ~/hanovatech/logs/

echo "Server gestartet um 08:00" > start.log
echo "User admin eingeloggt um 08:05" >> start.log
echo "Datum: $(date)" >> start.log
cat start.log
Teil B — System-Infos sammeln (10 min)
  1. Schreibe die Liste aller Dateien in /etc/ (long format) in eine Datei etc_inhalt.log.
  2. Versuche cd /existiert_nicht/ und leite den Fehler in fehler.log um.
  3. Schreibe in system_info.log drei Zeilen mit Username, Hostname und aktuellem Datum (mit drei echo-Befehlen + >>).
  4. Schreibe in eine Datei alles.log sowohl stdout als auch stderr von ls /etc /existiert_nicht.
bash
# 5)
ls -la /etc/ > etc_inhalt.log

# 6)
cd /existiert_nicht/ 2> fehler.log

# 7)
echo "User: $USER" > system_info.log
echo "Host: $(hostname)" >> system_info.log
echo "Date: $(date)" >> system_info.log

# 8) stdout + stderr in eine Datei
ls /etc /existiert_nicht &> alles.log
# alternativ: ls /etc /existiert_nicht > alles.log 2>&1
Teil C — Wildcards-Detektivarbeit (15 min)
  1. Erzeuge mit einem einzigen touch die Dateien test1.txt bis test10.txt. Tipp: Brace Expansion.
  2. Liste alle Dateien auf, die mit test beginnen.
  3. Liste nur die Dateien, die mit test beginnen und genau eine Ziffer haben (also test1.txt bis test9.txt, nicht test10).
  4. Liste nur test1.txt, test3.txt, test5.txt.
  5. Erzeuge zusätzlich: report_anna.txt, report_bernd.txt, daten_2024.csv, daten_2025.csv.
  6. Liste alle report_-Dateien auf.
  7. Liste alle .csv-Dateien auf.
bash
# 9)
touch test{1..10}.txt

# 10)
ls test*

# 11) nur einstellige Zahlen → ? deckt genau 1 Zeichen ab
ls test?.txt
# matched test1.txt bis test9.txt — test10.txt fällt raus, weil "10" zwei Zeichen sind

# 12) nur 1, 3, 5
ls test[135].txt

# 13)
touch report_anna.txt report_bernd.txt daten_2024.csv daten_2025.csv

# 14)
ls report_*

# 15)
ls *.csv
Teil D — Aufräumen mit Wildcards (10 min)
  1. Lösche alle test*.txt-Dateien mit einem Befehl.
  2. Lösche alle .csv-Dateien mit einem Befehl.
  3. Lösche alle report_-Dateien.
  4. Lass dir mit ls -l bestätigen: nur die *.log-Dateien (start.log, etc_inhalt.log, fehler.log, system_info.log, alles.log) sind übrig.
bash
# 16)
rm test*.txt

# 17)
rm *.csv

# 18)
rm report_*

# 19)
ls -l
# erwartet: nur die *.log-Dateien
🌟 Bonus für schnelle Teilnehmer
  1. Zähle mit wc -l wieviel Zeilen etc_inhalt.log insgesamt hat (Pipe!).
  2. Schreibe in einer einzigen Zeile sowohl auf den Bildschirm als auch in eine Datei system.log: "Test um $(date)". Tipp: tee.
  3. Erstelle mit Brace Expansion 10 Backup-Dateien: backup_2024-01.tar.gz bis backup_2024-10.tar.gz.
bash
# 20)
cat etc_inhalt.log | wc -l
# oder einfacher: wc -l etc_inhalt.log

# 21)
echo "Test um $(date)" | tee system.log

# 22)
touch backup_2024-{01..10}.tar.gz
🎉
Lab 1.3 geschafft?

Wenn ja: das war das letzte Lab von Tag 1. Du beherrschst jetzt das Erzeugen, Verwalten und schnelle Filtern von Dateien. Zeit für das Tages-Quiz und das Cheat-Sheet!

🎯

Kontrollfragen zum Kapitel

Selbst-Check
  1. Was unterscheidet echo "$USER" von echo '$USER'?
  2. Was bedeuten die drei Wildcards *, ?, [abc]?
  3. Wer löst Wildcards auf — die Shell oder der aufgerufene Befehl?
  4. Was unterscheidet Wildcards von Brace Expansion {1..10}?
  5. Welche Nummern haben stdin, stdout und stderr?
  6. Was ist der Unterschied zwischen > und >>?
  7. Wie leitest du nur Fehler in eine Datei um?
  8. Wie leitest du stdout UND stderr in dieselbe Datei? Nenne zwei Schreibweisen.
  9. Wozu ist /dev/null da?
  10. Wofür nutzt man tee?
  1. Double Quotes werten Variablen aus ($USER → admin). Single Quotes geben den Text wörtlich ($USER → $USER).
  2. * = beliebig viele Zeichen, ? = genau ein Zeichen, [abc] = ein Zeichen aus der Liste.
  3. Die Shell löst Wildcards auf, BEVOR der Befehl aufgerufen wird. Der Befehl sieht nur die fertige Liste.
  4. Wildcards matchen existierende Dateien. Brace Expansion erzeugt Text-Listen unabhängig von der Existenz.
  5. stdin = 0, stdout = 1, stderr = 2.
  6. > überschreibt die Zieldatei. >> hängt an.
  7. befehl 2> fehler.log
  8. befehl &> datei (kurz) oder befehl > datei 2>&1 (klassisch).
  9. /dev/null ist eine „Mülltonne“ — alles, was reingeht, ist weg. Praktisch um unerwünschte Ausgabe oder Fehler verschwinden zu lassen.
  10. tee schreibt stdin gleichzeitig auf stdout UND in eine Datei. Klassisch fürs Loggen + Anzeigen, und um in geschützte Dateien zu schreiben (echo X | sudo tee -a /etc/...).