Abschließende Anmerkungen

Bei allen hier durchgenommenen Befehlen gibt es üblicherweise noch viele weitere nützliche und hilfreichen Optionen, die in den manual pages beschrieben werden. Wenn euch also ein Befehl interessiert und ihr wissen wollt was der sonst noch mehr kann, einfach "man BEFEHLSNAME" eingeben.

Fast immer können so Sachen auch per Suchmaschine im Web aufgefunden werden, wenn ich einen spezifischen Anwendungsfall brauche. Zum Beispiel wenn ich die Dateien im Verzeichnis nach Datum sortieren will, suche ich nach "bash sort files by date" und erhalte gleich mal die Info, dass das mit "ls -t" geht. Generell ists aber nie verkehrt sich den Blick in die man pages etwas anzueignen, weil da oft Sachen zu finden sind, an die mensch gar noch nicht gedacht hat, die aber so manches vereinfachen können.

Hier haben wir nun noch zwei Abschnitte, die wir in unserer ursprünglichen Workshopplanung drin hatten, weil sie an sich schon spannend und auch hiflreich sein können. Allerdings hat sich bisher in allen Workshops gezeigt, dass sich das zeitlich nicht mehr ausgeht. Daher haben wir sie mal hier für besonders Motivierte bzw. zum Daheim weiterlesen angehängt.

Noch zwei praktische Linux(/Unix)-Konzepte: standard streams und pipelines

Bisher haben wir immer Befehle ausgeführt und direkt am Terminal die Ausgabe dazu erhalten. Es ist aber auch Möglich die Ausgabe eines Befehls umzuleiten, z.B. in eine Datei. Genau so ist es möglich die Eingabe eines Befehls umzuleiten, so dass sie nicht (via bash/Terminal) von der Tastatur kommt, sondern z.B. von einem File. Generell hat jeder Prozess drei Standard Streams, also drei Standard-Datenströme, die dem Prozess die Kommunikation mit der Umgebung ermöglichen. Das sind: stdin (Standard Input), stdout (Standard Output) und stderr (Standard Error). Klassischerweise kommt stdin von der Tastatur und stdout sowie stderr gehen aufen den Bildschirm. Für bestimmte Zwecke können hier aber Umleitungen sehr praktisch sein.

Schauen wir uns das anhand eines Beispiels an.

Hier geben wir einfach nur eine normale Meldung mittels echo aus:

$ echo "hallo, ich bin eine logmeldung"  
hallo, ich bin eine logmeldung

Das kennen wir schon. Aber unter Umständen wollen wir das gar nicht direkt ausgeben, sondern in eine Dateischreiben. Dazu leiten wir die Standardausgabe um, und zwar geht das mit einem ">" Zeichen:

$ echo "hallo, ich bin eine logmeldung" > logfile

Der Befehl hat nun keine Ausgabe produziert. Oder so scheint es. Am Bildschirm wurde zumindest nichts ausgebgeben. Wenn wir uns aber das aktuelle Directory anschauen, müsste hier nun eine Datei "logfile" zu finden sein. Wenn wir die Ausgeben erhalten wir die Meldung:

$ cat logfile  
hallo, ich bin eine logmeldung

Bei Verwendung von ">" zur Umleitung in eine Datei, wird die Datei bei jedem Schreibvorgang neu angelegt, also überschrieben. Ihr könnt die obige Umleitung mehrmals testen, es wird am Ende immer der gleiche Inhalt in der "logfile" Datei stehen. Manchmal will ich aber verschiedene Logmeldungen durch verschiedene Programmaufrufe aneinanderreihen. Die Daten sollen also am Ende der Datei angehängt werden. Dazu wird der ">" Operator doppelt verwendet, also ">>" (sollte die betroffene Logdatei noch nicht existieren wird sie einfach angelegt, gleich wie bei der Verwendung von ">" - nur wenn sie schon exisiter wird einfach an deren Ende weitergeschrieben). Schreiben wir so einfach nochmals ein paar Inhalte in die selbe Logdatei:

$ echo lala >> logfile  
$ echo lala >> logfile  
$ echo lala >> logfile  
$ echo lala >> logfile

Und nun lassen wir uns anzeigen was drin steht:

$ cat logfile  
hallo, ich bin eine logmeldung  
lala  
lala  
lala  
lala

Ein weiteres hilfreiches Feature in der Shell ist hier die command substitution. Ich kann in einer Kommandozeile ein `kommando` verwenden (inklusiver der back-ticks), dann wird zuerst dieses Kommando ausgeführt und dessen Inhalt an die jeweilige Stelle gesetzt. Dann wird erst die ursprüngliche Kommandozeile ausgeführt. Ein Beispiel (wir verwenden hier date um eine Zeitangabe anzuzeigen):

$ date
Mon Dez  5 17:06:36 CET 2016
$ echo "Es ist gerade `date` und nichts besonderes ist passiert"
Es ist gerade Mon Dez  5 17:06:51 CET 2016 und nichts besonderes ist passiert

Das können wir jetzt verwenden um eine Logdatei mit Zeitangaben zu schreiben:

$ echo "`date`: es ist gerade nichts passiert ... aber die Zeit vergeht" >> date.log
$ echo "`date`: es ist gerade nichts passiert ... aber die Zeit vergeht" >> date.log
$ echo "`date`: es ist gerade nichts passiert ... aber die Zeit vergeht" >> date.log
$ cat date.log
Mon Dez  5 17:09:17 CET 2016: es ist gerade nichts passiert ... aber die Zeit vergeht
Mon Dez  5 17:09:29 CET 2016: es ist gerade nichts passiert ... aber die Zeit vergeht
Mon Dez  5 17:09:39 CET 2016: es ist gerade nichts passiert ... aber die Zeit vergeht

Bis jetzt haben wir nur die Standardausgabe umgeleitet. Es ist aber auch möglich, die Fehlermeldungen (stderr) umzuleiten, die ein Programm erzeugt. Dazu muss mensch wissen, dass die standard streams auch durch Nummern gekennzeichnet werden können (stdin = 0, stdout = 1 und stderr = 2). So kann die jeweilige Kennung vor den Umleiteoperator gestellt werden. Das wird aber üblicherweise nur im Fall von stderr benötigt, weil die bash beim Umleiten einer Ausgabe standardmäßig 1 und beim Umleiten einer Eingabe standardmäßig 0 annimt, wenn nichts explizit angegeben wird. Folgende zwei Befehlen machen also genau das gleiche.

$ echo "hallo, ich bin eine logmeldung" >> output.log 2>> errors.log
$ echo "hallo, ich bin eine logmeldung" 1>> output.log 2>> errors.log

Nachdem echo keine Fehlermeldungen produziert, stehen hier nun zwei idente Zeilen im output.log und das errors.log ist zwar angelegt, aber leer. Verwenden wir nun ein listing, einmal auf eine vorhanden und einmal auf eine nicht vorhandene Datei mit den selben Umleitungen, und lassen uns die Inhalte der beiden Dateien anzeigen:

$ ls -l output.log >> output.log 2>> errors.log
$ ls -l ladidanichtvorhandenedatei >> output.log 2>> errors.log
$ cat output.log
hallo, ich bin eine logmeldung
hallo, ich bin eine logmeldung
-rw-rw-r-- 1 jackie jackie 62 Dez  5 17:18 output.log
$ cat errors.log
ls: cannot access ladidanichtvorhandenedatei: No such file or directory

Beim Ausführen des ersten ls Befehls trat kein Fehler auf, und der normale Output wurde an die output.log angehängt. Beim zweiten Befehl gab es keinen normalen Output, weil die fragliche Datei gar nicht vorhanden ist, also wurde nichts weiter in das output.log geschrieben. Allerdings trat ein Fehler auf (weil die Datei ja nicht vorhanden ist und uns ls das freundlicherweise mitteilen mag), daher wurde nun eine Zeile in die errors.log geschrieben.

So viel zu den Umleitungen. Was wir noch nicht probiert haben ist stdin umzuleiten. Aber dazu später mehr. Wer mehr zu den standard streams wissen möchte wir wieder mal in der Wikipedia fündig. Unter anderem gibts da auch eine kleine Grafik die das Konzept veranschaulicht: https://en.wikipedia.org/wiki/Standard_streams

Ein verwandtes bzw. darauf aufbauendes Konzept sind pipelines (oder kurz: pipes). Bei diesen geht es darum den Output eines Kommandos direkt in den Input eines folgenden Kommandos umzuleiten (während stderr bei allen Befehlen weiterhin in der startenden shell, also üblicherweise am Bildschirm bleibt). Auch hier gibts eine grafische Veranschaulichung und Hintergrundinfos auf https://en.wikipedia.org/wiki/Pipeline_(Unix)

Schauen wir uns das Ganze wieder anhand von Beispielen an. Ein Directory Listing kann mitunter ganz lang sein, und daher ist es manchmal praktisch dieses Listing in ein Pager-Programm umzuleiten (in dem wir alles Seite für Seite anschauen und rauf und runterscrollen können). So ein Programm ist z.B. less. Es zeigt einfach die Inhalte einer Datei an, wenn es eine Datei als Argument bekommt. Oder, wenn keine Datei übergeben sondern ein Standardinput verwendet wird, dann wird eben dieser Inhalt angezeigt. Dabei kann mensch mit Leertaste oder "b" jeweils eine Seite hinunter- oder hinauf-scrollen. "q" beendet das Programm wieder. (Mehr Infos zu less gibts mit "man less"). Lassen wir uns also mal ein längeres Listing mittels einer pipe in less hineinfüttern:

$ ls -l /etc | less

Das selbe hätte ich mit den Dateiumleitungen von oben so erreichen können, indem ich im ersten Befehl den Output in eine Datei umleite und im zweiten Befehl den Inhalt der Datei als stdin in den Befehl füttere. Also wie in den folgenden beiden Zeilen:

$ ls -l /etc > zwischenablage.txt
$ less < zwischenablage.txt

Die pipe macht das aber automagisch für mich, ohne dass extra eine Datei angelegt werden muss (die ich danach ja vielleicht auch wieder löschen muss, wenn ich nicht irgendwann einen Haufen unnötiger Dateien herumliegen haben will). Wie praktisch das sein kann wird noch klarer, wenn ich viele Befehle aneinanderreihe um komplexere Dinge zu erreichen. Zum Beispiel kann ich "grep" verwenden um in Dateien (oder im stdin) nach Inhalten zu suchen und nur jene Zeilen auszugeben, in denen der Inhalt vorkommt (oder, mit der Option -v nur jene Zeilen in der der Inhalt nicht vorkommt - mehr Infos dazu mit "man grep"). Aber nun ein Beispiel:

$ ls -l /etc | grep "Aug" | less

Wir haben uns hier nur jene Zeilen aus dem Listing anzeigen lassen, die irgendwo in der Zeile "Aug" beinhalten. Da sind vor allem dann jene Zeilen dabei, die in einem Aug angelegt bzw. zuletzt geändert wurden. Wir können uns aber auch alle Zeilen (die ja Dateien und oder Verzeichnisse repräsentieren) anzeigen lassen, in denen nicht "Aug" vorkommt:

$ ls -l /etc | grep -v "Aug" | less

Jetzt könnten wir das ganze aber nochmal mit einem weiteren grep filtern lassen:

$ ls -l /etc | grep -v "Aug" | grep "2016" | less

Wir haben uns nun alle Einträge anzeigen lassen, die nicht "Aug" beinhalten aber "2016" - die Idee ist, sich alle Dateien/Verzeichnisse anzuzeigen die zuletzt 2016 modifiziert wurden, allerdings nicht im August. Wichtig ist aber, dass hier auch Dateien vorkommen könnten die im Dateinamen "2016" stehen haben und vielleicht aber 2014 das letzte mal geändert wurden. Insofern ists manchmal sinnvoll nach " Aug " anstatt "Aug" oder nach " 2016 " anstatt "2016" zu suchen. Wie immer ists beim Filtern wichtig zu wissen wie das Format ausschaut, das ich dann filtern will.

Was tu ich wenn ich mich aussperre (also z.B. das root Passwort vergessen habe):

Sollte mensch sich einmal komplett aus dem eigenen System aussperren, kann unter Umständen - je nach dem wie sicher das System konfiguriert ist - das root passwort resetted werden. In der Standardkonfiguration ist das meist (mit ein bisschen Übung) nicht so aufwändig, ein Beispiel dazu gibt es hier:

http://www.debianadmin.com/how-to-reset-debian-root-password.html

Je nach Distribution und Version können die notwendigen Optionen im Boot loader aber unterschiedlich heißen und es kann mitunter ein bisschen experimentieren notwendig werden. Auch andere Wege sind möglich, z.B. booten von einem Live-Stick, dann die Festplatte einhängen und die shadow Datei manipulieren. Das kann allerdings auch über die richtigen BIOS- bzw. UEFI-Einstellungen verhindert werden.

Das System kann auch durchaus so abgesichert werden, dass das gar nicht mehr möglich ist (z.B. mit komplett verschlüsselter Festplatte). In dem Fall ists aber auch so, dass er das zentrale Passwort vergisst halt dann auch damit leben muss, dass das System nur mehr neu installiert werden kann.

results matching ""

    No results matching ""