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:
| Kanal | Nummer | Wofür |
|---|---|---|
| stdin | 0 | Eingabe, die in den Befehl hineinfließt (standard input). |
| stdout | 1 | Die normale Ausgabe (standard output). |
| stderr | 2 | Fehlermeldungen (standard error). Getrennt, damit sie nicht in den Ergebnissen landen. |
Ausgabe in Dateien schreiben
| Eingabe | Was passiert |
|---|---|
| ls -l > liste.txt | Die Ausgabe landet in liste.txt statt auf dem Bildschirm. Gibt es die Datei schon, wird sie überschrieben. |
| echo Text >> log.txt | Zwei >> hängen die Ausgabe an das Ende an. Der alte Inhalt bleibt. |
| wc -l < liste.txt | Umgekehrt: 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 ZeileEnter 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.
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.
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.txtEin 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
5Dafür gibt es eine Reihe von Befehlen, die Text aus einer Pipe lesen und umformen:
| Befehl | Was er tut |
|---|---|
| wc -l | Zählt die Zeilen (word count, -l für lines). |
| sort | Sortiert alphabetisch. -n nach Zahlenwert, -r umgekehrt. |
| uniq -c | Fasst gleiche Zeilen, die direkt untereinander stehen, zusammen und zählt sie. Deshalb immer erst sortieren. |
| cut -d: -f1 | Schneidet eine Spalte aus. -d nennt das Trennzeichen, -f die Nummer der Spalte (field). |
| grep | Filtert 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, tail | Nur 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/bashZä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.
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 | sortEin 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:
| Eingabe | Was passiert |
|---|---|
| befehl 2> fehler.txt | Fehlermeldungen in eine Datei, die normale Ausgabe bleibt auf dem Bildschirm. |
| befehl 2>/dev/null | Fehlermeldungen wegwerfen. /dev/null ist ein Gerät, das alles schluckt, was man hineinschreibt. |
| befehl > alles.txt 2>&1 | Beides 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.
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.
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/nullEin 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.
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.
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.txtEin 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
13Unter Windows
Jetzt selbst testen
Vier Fragen zum Abschluss. Du hast so viele Versuche, wie du willst.
In log.txt stehen 100 Zeilen. Was steht nach echo fertig > log.txt darin?
Warum steht vor uniq -c fast immer ein sort?
Was bewirkt 2>/dev/null am Ende eines Befehls?
Was gibt cut -d: -f1 /etc/passwd aus?