Lektion 6 von 6

Pipes und Umleitung

Die eigentliche Stärke des Terminals: Ausgaben in Dateien schreiben, Fehlermeldungen getrennt behandeln und kleine Befehle mit | zu einer Kette verbinden, die in einer Zeile auswertet, wofür man sonst ein Programm bräuchte.

  • Etwa 35 Minuten
  • 3 Übungen und 1 Knobelaufgabe im Terminal, 4 Quizfragen
  • Terminal im Browser

Drei Kanäle

Jeder Befehl hat drei Kanäle, über die Text fließt. Bisher landete alles auf dem Bildschirm, aber du kannst jeden Kanal umleiten:

KanalNummerWofür
stdin0Eingabe, die in den Befehl hineinfließt (standard input).
stdout1Die normale Ausgabe (standard output).
stderr2Fehlermeldungen (standard error). Getrennt, damit sie nicht in den Ergebnissen landen.

Ausgabe in Dateien schreiben

EingabeWas passiert
ls -l > liste.txtDie Ausgabe landet in liste.txt statt auf dem Bildschirm. Gibt es die Datei schon, wird sie überschrieben.
echo Text >> log.txtZwei >> hängen die Ausgabe an das Ende an. Der alte Inhalt bleibt.
wc -l < liste.txtUmgekehrt: Der Befehl liest seine Eingabe aus der Datei.

Mit echo und > schreibst du schnell eine Zeile in eine Datei, ganz ohne Texteditor. Enthält der Text Leerzeichen, setze ihn in Anführungszeichen. Bei Sonderzeichen wie ! oder $ nimm einfache Anführungszeichen '…', denn in doppelten wertet die Bash sie noch aus.

azubi@lernarena:~$ echo "Erste Zeile" > test.txt
azubi@lernarena:~$ echo "Zweite Zeile" >> test.txt
azubi@lernarena:~$ cat test.txt
Erste Zeile
Zweite Zeile
azubi@lernarena: ~
Willkommen im Übungs-Terminal von Lernarena. Probier: ls > liste.txt, cat liste.txt, cut -d: -f1 /etc/passwd | sort

Enter führt aus, Tab ergänzt Namen, Pfeil hoch holt frühere Befehle, Bild hoch blättert zurück. Esc und dann Tab verlässt das Terminal.

Übung 6.1

Schreib mit echo die Zeile Server web01 geprüft in die neue Datei protokoll.txt. Hänge danach die Zeile Backup ok an, ohne die erste zu verlieren. Speichere zum Schluss die Ausgabe von ls -l in der Datei liste.txt.

azubi@lernarena: ~

Enter führt aus, Tab ergänzt Namen, Pfeil hoch holt frühere Befehle, Bild hoch blättert zurück. Esc und dann Tab verlässt das Terminal.

Ziele

  • Schreib mit echo die Zeile „Server web01 geprüft“ in die neue Datei protokoll.txt (offen)
  • Hänge die Zeile „Backup ok“ an, ohne die erste zu verlieren (offen)
  • Speichere die Ausgabe von ls -l in der Datei liste.txt (offen)

Musterlösung anzeigen
echo "Server web01 geprüft" > protokoll.txt
echo "Backup ok" >> protokoll.txt
ls -l > liste.txt
cat protokoll.txt

Ein möglicher Weg. Andere Wege sind genauso richtig, geprüft wird nur das Ergebnis. Hast du beim zweiten Mal nur ein > getippt, ist die erste Zeile weg. Dann einfach beide Befehle noch einmal richtig.

Befehle verketten mit |

Das Zeichen | heißt Pipe (Rohr). Es leitet die Ausgabe des linken Befehls direkt als Eingabe in den rechten, ohne Umweg über eine Datei. So lassen sich kleine Befehle wie Bausteine zusammenstecken:

azubi@lernarena:~$ cat /etc/passwd | wc -l
5

Dafür gibt es eine Reihe von Befehlen, die Text aus einer Pipe lesen und umformen:

BefehlWas er tut
wc -lZählt die Zeilen (word count, -l für lines).
sortSortiert alphabetisch. -n nach Zahlenwert, -r umgekehrt.
uniq -cFasst gleiche Zeilen, die direkt untereinander stehen, zusammen und zählt sie. Deshalb immer erst sortieren.
cut -d: -f1Schneidet eine Spalte aus. -d nennt das Trennzeichen, -f die Nummer der Spalte (field).
grepFiltert Zeilen, auch mitten in einer Kette. Mit -o nur den passenden Teil statt der ganzen Zeile, zum Beispiel grep -o 'from [0-9.]*': das Wort „from“, ein Leerzeichen und dann beliebig viele Ziffern und Punkte.
head, tailNur die ersten oder letzten Zeilen, zum Beispiel die ersten drei einer Rangliste.

In /etc/passwd stehen die Angaben eines Benutzers in Spalten, getrennt durch Doppelpunkte. Ganz vorn steht der Name:

azubi:x:1000:1000:Azubi:/home/azubi:/bin/bash
Übung 6.2

Zähle mit einer Pipe, wie viele Zeilen /etc/passwd hat, also wie viele Benutzer es gibt. Zeige danach nur die Benutzernamen, alphabetisch sortiert: erst mit cut die erste Spalte ausschneiden, dann mit | an sort weiterreichen.

azubi@lernarena: ~

Enter führt aus, Tab ergänzt Namen, Pfeil hoch holt frühere Befehle, Bild hoch blättert zurück. Esc und dann Tab verlässt das Terminal.

Ziele

  • Zähle mit einer Pipe, wie viele Zeilen /etc/passwd hat (offen)
  • Zeige nur die Benutzernamen aus /etc/passwd, alphabetisch sortiert (offen)

Musterlösung anzeigen
cat /etc/passwd | wc -l
cut -d: -f1 /etc/passwd | sort

Ein möglicher Weg. Andere Wege sind genauso richtig, geprüft wird nur das Ergebnis. Auf einem echten Server stehen in /etc/passwd noch viele weitere Systembenutzer, oft über 30 Zeilen.

Fehlermeldungen umleiten

Fehlermeldungen laufen über Kanal 2 und kommen deshalb an > vorbei. Für sie gibt es eigene Zeichen:

EingabeWas passiert
befehl 2> fehler.txtFehlermeldungen in eine Datei, die normale Ausgabe bleibt auf dem Bildschirm.
befehl 2>/dev/nullFehlermeldungen wegwerfen. /dev/null ist ein Gerät, das alles schluckt, was man hineinschreibt.
befehl > alles.txt 2>&1Beides in dieselbe Datei: Kanal 2 geht dorthin, wohin Kanal 1 gerade zeigt.

Typischer Fall: Du durchsuchst /etc, aber einige Dateien darfst du nicht lesen. Zwischen den Treffern stehen dann lauter Permission denied. Mit 2>/dev/null siehst du nur noch die Treffer.

Übung 6.3

Leite die Fehlermeldung von ls gibtsnicht mit 2> in die Datei fehler.txt um. Suche danach mit grep -r nach PermitRootLogin in /etc, zuerst ohne und dann mit 2>/dev/null, damit keine Fehlermeldung mehr erscheint.

azubi@lernarena: ~

Enter führt aus, Tab ergänzt Namen, Pfeil hoch holt frühere Befehle, Bild hoch blättert zurück. Esc und dann Tab verlässt das Terminal.

Ziele

  • Leite die Fehlermeldung von ls gibtsnicht in die Datei fehler.txt um (offen)
  • Suche mit grep -r nach PermitRootLogin in /etc, ohne dass Fehlermeldungen erscheinen (offen)

Musterlösung anzeigen
ls gibtsnicht 2> fehler.txt
cat fehler.txt
grep -r PermitRootLogin /etc 2>/dev/null

Ein möglicher Weg. Andere Wege sind genauso richtig, geprüft wird nur das Ergebnis. Die Meldung zu /etc/shadow verschwindet, der Treffer in /etc/ssh/sshd_config bleibt. PermitRootLogin no heißt übrigens: root darf sich nicht direkt per SSH anmelden. Das ist eine wichtige Sicherheitseinstellung.

Zum Knobeln 6.4

Diese Aufgabe ist freiwillig, hier steht nicht genau, wie es geht. In Lektion 4 hast du die Adresse mit den meisten Fehlversuchen in /var/log/auth.log noch selbst heraussuchen müssen. Jetzt soll eine einzige Zeile eine Rangliste erstellen: Welche IP-Adresse hatte wie viele Fehlversuche, die häufigste oben. Speichere das Ergebnis in rangliste.txt.

azubi@lernarena: ~

Enter führt aus, Tab ergänzt Namen, Pfeil hoch holt frühere Befehle, Bild hoch blättert zurück. Esc und dann Tab verlässt das Terminal.

Ziele

  • Erstelle in rangliste.txt eine Rangliste der Adressen mit Fehlversuchen, die häufigste oben (offen)

Musterlösung anzeigen
grep Failed /var/log/auth.log | grep -o 'from [0-9.]*' | sort | uniq -c | sort -nr > rangliste.txt
cat rangliste.txt

Ein möglicher Weg. Andere Wege sind genauso richtig, geprüft wird nur das Ergebnis. Lies die Kette von links nach rechts: Zeilen mit Failed, daraus nur „from“ und die Adresse, sortieren, gleiche zählen, nach Anzahl absteigend sortieren, in die Datei. In [0-9.]* stehen die eckigen Klammern für „eine Ziffer oder ein Punkt“, der Stern für „beliebig oft“. Genau so werten Administratoren Protokolle aus, bevor sie eine Adresse sperren.

Sehen und speichern mit tee

Manchmal willst du eine Ausgabe sehen und gleichzeitig speichern. tee funktioniert wie ein T-Stück in einer Wasserleitung: Es schreibt alles auf den Bildschirm und zusätzlich in eine Datei. Mit -a hängt es an, statt zu überschreiben.

azubi@lernarena:~$ grep -c Failed /var/log/auth.log | tee anzahl.txt
13

Unter Windows

Jetzt selbst testen

Vier Fragen zum Abschluss. Du hast so viele Versuche, wie du willst.

1 / 4

In log.txt stehen 100 Zeilen. Was steht nach echo fertig > log.txt darin?

2 / 4

Warum steht vor uniq -c fast immer ein sort?

3 / 4

Was bewirkt 2>/dev/null am Ende eines Befehls?

4 / 4

Was gibt cut -d: -f1 /etc/passwd aus?