Hobbes_
Gast
Dies ist Teil 2 eines Tutorials zu Terminal
Inhalt
Teil 1
(0) Einleitung
(1) Das Programm
(2) Unix als System
(3) man
(4) Einige Befehle
Teil 2
(5) I/O-Redirection / Pipes und Wildcards / Regular Expressions
(6) Editoren vi/vim, Emacs und nano
(7) "Pimp my Terminal"
Teil 3
(7) "Pimp my Terminal" (Fortsetzung)
(8) User / Admin / Superuser
Teil 4
(8) User / Admin / Superuser (Fortsetzung)
(9) Wie komme ich zu UNIX-Programmen?
Teil 5
(9) Wie komme ich zu UNIX-Programmen? (Fortsetzung)
Teil 6
(10) Einige Unterschiede zwischen Darwin und anderen UNICES
(11) Weitere Informationen / Referenzen / Links
Dank
-------------
(5) I/O-Redirection / Pipes und Wildcards / Regular Expressions
Info: Diese beiden Dinge schaut man sich besser mit frischem Kopf an
(5.1) I/O-Redirection und Pipes
Generell verarbeiten Computerprogramme Daten. Dazu werden Eingaben benutzt und das Resultat ausgegeben. Ein Programm hat grundsätzlich folgende Eingabemöglichkeiten:
Daneben bestehen foldende Ausgabemöglichkeiten:
(5.1.1) I/O Redirection
Die standardmässig im Programm angewandten Ein- und Ausgabekanäle (stdIn, stdOut, stdError) sind zwar meist auf das Terminal gerichtet, können jedoch gelegentlich auch auf Dateien gerichtet sein. Diese Standard-Kanäle können einfach umgeleitet werden.
Beispiel: Schauen wir uns nochmals das aktuelle Verzeichnis an:
$ ls -l
Wir können diese lange Liste auch in eine Datei umleiten, so dass wir später noch damit arbeiten können. Wir benutzen dazu
$ ls -l >~/dummy_test_liste.txt
> leitet die Standardausgabe in die direkt dahinter angegebene Datei um.
Wichtig: Mit dieser Methode wird eine neue Datei begonnen. Wenn vorher schon eine Datei mit gleichem Namen bestand, so wird sie damit einfach überschrieben! Dies geschieht ohne Nachfrage bei Dir, ob Dir das recht ist (nur so als Info...).
Alternativ kann das Symbol >> anstelle von > verwendet werden. Dann wird die Datei nicht gelöscht, sondern der neue Inhalt an den alten Inhalt hinten angefügt. Dies eignet sich insbesondere zur Ergänzung einer Protokolldatei.
Wir können nun mit dieser Datei arbeiten. Am einfachsten schauen wir sie uns einfach mal an.:
$ less ~/dummy_test_liste.txt
Wir können auch die Anzahl der Zeilen ansehen (siehe man wc, wie immer
):
$ wc -l ~/dummy_test_liste.txt
Das umgekehrte zur Umleitung der Ausgabe (>) ist die Umleitung der Eingabe mittels <. Als Beispiel zeigen wir, dass less nicht nur eine Datei benutzerfreundlich anzeigen kann, sondern auch Daten aus der Standardeingabe. Dies macht im Moment nicht sehr viel Sinn. Später werden wir den Sinn dahinter dann begreifen.
$ less <~/dummy_test_liste.txt
(5.1.2) Pipes
Wie bereits erwähnt, beruht eines der Konzepte in UNIX darin, Probleme nicht mit grossen Programmen zu lösen, sondern kleine, jedoch stabile und an Optionen mächtige Mini-Programme zB. in Scripts zusammenzufassen. Ein Teil dieses Konzepts sind Verbindungskanäle (Pipes), die es erlauben, die Ausgabe eines Programms direkt als Eingabe für ein anderes zu verwenden. Du kannst Dir dabei vorstellen, dass die Umleitung in eine Datei mittels > und das Einlesen dieser Information mittels < in einem Schritt zusammengefasst wird. Man benutzt dazu das Symbol |. Das coole an diesem Konzept ist, dass man sich diese Zwischendatei sogar sparen kann, wenn man sie später nicht sonst noch für eine Aufgabe benötigt.
Benutzen wir als Beispiel nochmals
$ ls -l
Wir sehen eine lange Liste an Dateien. Auf unserem modernen Terminal können wir bequem hunderte Zeilen nach oben scrollen. Dies war auf alten Konsolen mit fixierter Zeilenzahl nicht möglich, so dass man oft darauf angewiesen war, die Informationen auf Seiten aufteilen zu lassen (die verwendeten Programme nannte man Pager: more, less). less haben wir ja bereits mehrfach benutzt. Unter anderem wird es ja auch von man benutzt. Lassen wir uns also die lange Dateiliste seitenweise darstellen:
$ ls -l | less
Dabei können wir in less auf alle Funktionen zurückgreifen. Wir können neben dem Blättern auch die Suchfunktion benutzen, wie wir das in Teil 1 bereits gesehen haben.
Wir können uns so einfach auch die Anzahl der Zeilen ausgeben lassen (wie bereits oben mit dem Umweg über die Datei):
$ ls -l | wc -l
Achtung: Da ls -l als erste Zeile eine Informationszeile ausgibt, erhalten wir so zwar die Anzahl der Zeilen, jedoch nicht die Anzahl der Dateien. Tja, in UNIX nimmt man's genau
Deshalb eignet sich folgender Befehl zur Eruierung der Anzahl der Dateien:
$ ls -1 | wc -l (Als Option bei ls eine 1 [eins] anstelle von l [kleines L], die Option für wc bleibt ein kleines L)
ls -1 (eins) gibt ganz brav eine Datei pro Zeile aus. Dabei werden keine zusätzlichen Informationen wie bei ls -l (kleines L) ausgegeben. Diese brauchen wir nur zum zählen auch nicht. Ausserdem werden weniger Rechenressourcen verbraucht. (Nebenbei: Im Kontext von Pipes kann man sich den Parameter -1 [eins] bei ls auch sparen, da er dann standardmässig benutzt wird: Man kann also anstelle von ls -1 | wc -l auch kurz ls | wc -l verwenden.)
Für unser nächstes Beispiel benutzen wir eine weiteres Programm grep. Dies ist ein sehr mächtiges Programm, mit dem sich innerhalb einer Datei Zeilen suchen lassen, die einem bestimmten Muster entsprechen (siehe regular expressions unten) in Dateien auswerten kann (Vorschlag: man grep
). Es bietet sich also sehr zur Verwendung innerhalb von Pipes an. Anbei nur ein simples Beispiel:
Beispiel: Wir suchen alle Kalendereinträge mit der Buchstaben-Kombination "LOTR" und sehen auf dem Bildschirm die zeitliche Abfolge einer berühmten "Kurzgeschichte".
$ grep "LOTR" /usr/share/calendar/calendar.history | less
(Jetzt bleibt nur noch das Problem, dass das Abenteuer im Dezember und nicht im Januar beginnt - doch das soll uns in unserer aktuellen technischen Betrachtung nicht stören)
Diese Umleitungen können noch weiter kombiniert werden. Auch kann die Fehlerausgabe ebenso umgeleitet werden: Einige Beispiele (Englisch)
Unser letztes Beispiel können wir nutzen, um die Dateien nach deren Grösse sortiert auszugeben (wir benutzen ls wieder mit der Option -l [kleines L]):
$ ls -l | sort -n +4 (kleinste Datei zuerst)
$ ls -l | sort -nr +4 (grösste Datei zuerst, reversed)
Wir können auch mal schauen, welches so die grössten Dateien unseres gesammten Benutzerverzeichnisses sind. Wir benutzen dabei eine Option -R (rekursiv) für ls. Dabei wird jedes passende Verzeichnis (mit der aktuellen Angabe alle) gleich nochmals zum durchsuchen verwendet.
$ ls -lR ~ | sort -nr +4 | less
Erklärung: ls generiert von unserem Benutzerverzeichnis ~ eine ausführliche Liste. Dabei wird es rekursiv auch auf Unterverzeichnisse angewandt. sort sortiert uns das ganze rückwärts nach der Dateigrösse (Spalte 5). less präsentiert uns das ganze geordnet auf dem Bildschirm.
(5.2) Wildcards und Regular Expressions
(5.2.1) Wildcards
Manchmal wünscht man einen Befehl nicht nur auf eine ganz genau definierte Datei anzuwenden, sondern auf alle Dateien, deren Namen gewissen Vorgaben enspricht. Dazu kann man in der Shell die Platzhalter * und ? (Wildcards genannt) einsetzen.
? bedeutet dabei genau ein Zeichen (1)
* bedeutet dabei keines, eines oder mehrere Zeichen (0 - n)
Beispiele:
*.jpg --> alle Dateien, die mit .jpg aufhören
*.doc --> alle Word-Dateien
* --> alle nicht-versteckten Dateien
So zeigt uns folgender Befehl alle JPG-Dateien des aktuellen Verzeichnisses an
$ ls *.jpg
Wichtig: Gerade die Anwendung von Wildcards kann teilweise unbeabsichtigte Effekte haben, wenn nicht peinlich auf die korrekte Schreibweise geachet wird. So darf beispielsweise kein Leerzeichen zwischen * und dem Rest sein, da sonst beide Elemente als separate Parameter interpretiert werden mit entsprechenden Konsequenzen. Bei ls kann dies mal zu einer komischen Ansicht führen. Bei rm, mv oder cp können die Folgen rasch verheerend sein!!!
Weiteres Beispiel: Zur Suche von bestimmten Dateien auch innerhalb der Unterverzeichnisse bietet sich das Programm find an (man find, wie immer
). Wir suchen nun alle Dateien mit .jpg unseres Verzeichnisses (inklusive Unterverzeichnisse).
$ find ~ -name "*.jpg" | less
Dieser Befehll istet uns in gewohnter auf die Seitengrösse zugeschnittener Art alle Dateien mit der Endung .jpg auf. Es gibt jedoch auch JPEG-Dateien, welche die Endung jpeg haben.
Wenn wir gleichzeitig nach .jpg und .jpeg suchen wollen, so erreichen wir dies mit einer Verknüpfung zweier Suchparameter mittels logischem ODER (Parameter –or bzw. –o):
$ find ~ -name "*.jpg" -or -name "*.jpeg" | less
Et voilà! So einfach ist das
(5.2.2) Regular Expressions
Neben den Wildcards bieten einige Programme noch die Möglichkeit an, reguläre Ausdrücke (regular expressions, regex) zur Definition eines Suchausdruckes zu verwenden. Wir haben von diese Programmen bereits grep, less und man kennengelernt. Auch bash unterstützt regex in Scripts, jedoch nicht allgemein für alle Programme im interaktiven Modus.
Es ist wichtig, regex von Grund auf zu lernen, so dass sich nicht unnötige Fehler einschleichen. Einen Start in die Welt der regex bieten die Links des Wikipedia-Artikels (deutsch, oder noch besser englisch). Anbei nur ganz kurz wichtige Unterschiede einiger in Wildcards und regex verwendeter Zeichen:
In regex beschreiben ? und * wieder die Anzahl der Elemente. Jedoch bezieht sich diese Quantität auf das Element, welches direkt davor steht. Auch kann ? der Quantität 0 entsprechen. Daneben ist vor allem wichtig, dass der Punkt eine funktionelle Bedeutung hat (irgend ein Zeichen). Wenn wir also verlangen, dass ein Punkt im Text vorkommen muss, so muss der Punkt speziell markiert (escape) werden: Ein Punkt wird als \. Geschrieben. Genauso müsen auch zahlreiche andere zeichen (zB. runde, eckige und geschweifte Klammern) escaped werden, wenn man nach ihnen als Zeichen suchen lassen will. So können die von der Shell bekannte Wildcard * folgendermassen in einer regex angegeben werden: .*
Beispiel: Selbstverständlich bietet auch find die Möglichkeit regex zu verwenden. Die oben angegebene Suche nach .jpg und .jpeg können wir beispielsweise wie folgt auch so formulieren:
$ find -E ~ -regex "^.*\.jp[e]?g" | less
Erklärung: Wir benutzen find mit der Option –E (erweiterte regex) für unser Verzeichnis ~. Den regulären Ausdruck platzieren wir hinter –regex. ^ verweist auf den Zeilenanfang. .* erlaubt eine beliebige Anzahl Zeichen vor dem Punkt \. (escaped!). Dann kommt unser Suffix: Es soll genau .jpg oder .jpeg lauten. Das Fragezeichen erlaubt wie oben erwähnt im Gegensatz zur Wildcard auch die Möglichkeit der Quantität 0 des definierten Zeichens e.
Alternativ kann man auch einen Suchausdruck verwenden, der das ganze vom Zeilenende ($) her definiert:
$ find -E ~ -regex ".*\.jp[e]?g$" | less
Wir sehen schon: Regex sind ausserordentlich hilfreich, insbesondere sie auch in verschiedenen Programmiersprachen verwendet werden können – obwohl es teilweise halt gewisse Unterschiede in den Details gibt.
Vorsicht: Auch regex bringen ein riesiges Fehlerpotential mit sich. So ist eine gute Dokumentation der Funktion unerlässlich. Oftmals ist diese deutlich länger als eine oft kryptisch aussehender regulärer Ausdruck.
(6) Editoren vi/vim, Emacs und nano
Editoren sind der Schlüssel zur Konfiguration von Unix. Alle Konfigurationsdateien sind in lesbarem Text gespeichert. Formal handelt es sich bei dem, was wir im Alltag als Editor bezichnen um "interaktive Text-Editoren", also um Programme, mit deren Hilfe wir selbst Texte interaktiv ändern können. Daneben gibt es noch eine Vielzahl anderer nicht-interaktiver Editoren, auf die wir hier nicht eingehen (Bsp: awk, sed, groff).
vi ist ein ausserordentlich mächtiges Werkzeug, er erschlägt den Neuling jedoch aufgrund der Vielzahl an Optionen. Er hat jedoch klar seine Bedeutung, da er standardmässig wohl auf jedem UNIX-System installiert ist und auch andere Programme darauf standardmässig zugreifen (zB. visudo). Selbstverständlich erlaubt die Suchfunktion ebenso reguläre Ausdrücke.
Darwin bringt die Weiterentwicklung vim mit. Die Dokumentation ist sehr umfangreich (Kurzanleitung).
Hier nur die wichtigste Kommandofolge: Wie komme ich aus dem Programm raus, ohne die Datei zu verändern: Link (die Tropfen, die Du nun auf dem Bildschirm siehst, sind meine Schweisstropfen, die sich mal bildeten, als ich eine Systemdatei als root mal mit vim anschauen wollte...).
Nun: Es geht auch frei von Angstschweiss: Für vi bietet Darwin ein eigenes interaktives Tutorial (Dauer ca. 30 Minuten). Viel Vergnügen:
$ vimtutor de (sogar in deutsch)
Ähnlich ist auch der Emacs eine Welt für sich. Man kann ihn sogar für Spiele benutzen.
Für den Einstig wesentlich praktischer ist ein kompakter Editor nano (siehe auch man nano). Wir schauen ihn kurz an, da wir ihn ihn der Folge benutzen werden
$ nano ~/irgendeine_datei.txt
--> Bildschirm mit Editierfähigkeit wie wir das von üblichen Editoren des Mac OS kennen. Er bietet den Vorteil, dass er seine wichtigen Befehle unten anzeigt, so dass er wirklich einfach zu benutzen ist.
Geben wir mal irgend einen Text ein.
Wir beenden ihn mit ctrl-x. Dabei fragt er automatisch, ob wir die Datei speichern wollen. y (yes) zum Speichern, n (no) zum Verwerfen des Textes. Nachdem wir yes gewählt haben, fragt er nochmals nach dem Dateinamen, den wir einfach mit der Return-Taste bestätigen können. Ganz einfach, ohne Schweisstropfen auf der Stirn
nano ist wirklich nur ein simpler Editor (für den raschen Start). Wer sich länger mit UNIX beschäftigt, lernt besser vi zu benutzen. Neben seinem Funktionsumfang gehört seine praktisch uneingeschränkte Verfügbarkeit auf praktisch jedem UNIX/Linux zu seinen Stärken. Ich erinnere nochmals an:
$ vimtutor de
(7) "Pimp my Terminal"
(7.1) Programm Terminal.app
Aufmerksame Leser haben es mittlerweile sicher bereits realisiert. Terminal selbst ist "nur" ein Programm, das die Eingabe und Ausgabe von Text ermöglicht. Damit wird eine Konsole (Bildschirm und Tastatur) simuliert. Diese Daten werden dann einer Shell nach eigener Wahl zur Verfügung gestellt. Wir erinnern uns: Zu Zeiten der Grossrechner hatte der Benutzer nur ein "dummes" Text-Eingabe-Gerät (Konsole, Terminal), welches über eine direkte Kabelverbindung oder prinzipiell unabhängig davon über eine längere geschützte Datenleitung mit dem Zentralrechner verbunden war. Auf diesem Rechner lief dann das Programm sh oder ein späteres Derivat.
So sehen wir, dass Terminal.app neben dem Standard 'neues Shell-Fenster' auf dem eigenen Computer auch die Möglichkeit bietet, sich auf einem anderen Server einzuloggen (Telnet uncodiert [davon ist abzuraten] oder SSH codiert; ein cooles Tutorial dazu gibt es von Cyrics). Abgesehen davon, dass das Ganze wegen der Datenkommunikation langsamer läuft, ist die Bedienung identisch. Auch muss man dieselbe Vorsicht walten lassen: Man kann auch auf Distanz einen Computer auseinander nehmen...
Das Terminal-Programm kann im Aussehen angepasst werden. Standardmässig hat es in der aktuellen Version in Tiger schwarze Zeichen (Font Monaco) vor einem weissen Hintergrund. Dazu dienen folgende Menüs:
Terminal --> Einstellungen (Auswahl der Shell möglich; ich würde daran nur etwas ändern, wenn ich genau weiss, was zu tun ist).
Terminal --> Fenstereinstellungen
(7.2) Shells
Die Benutzereingaben werden durch einen Kommandozeileninterpreter, eine sogenannte Shell verarbeitet und dann die entsprechenden Programme ausgeführt. Die Thompson-Shell (osh) war die erste UNIX-Standard-Shell. Die später entwickelte Bourne Shell sh ist sozusagen der Vorfahre der meisten heute gebräuchlichen Shells. Diese später entstandene Derivate boten besseren Bedienkomfort oder zusätzliche Funktionen. Kurz die wichtigsten vorgestellt:
Link: Fortsetzung Teil 3
Inhalt
Teil 1
(0) Einleitung
(1) Das Programm
(2) Unix als System
(3) man
(4) Einige Befehle
Teil 2
(5) I/O-Redirection / Pipes und Wildcards / Regular Expressions
(6) Editoren vi/vim, Emacs und nano
(7) "Pimp my Terminal"
Teil 3
(7) "Pimp my Terminal" (Fortsetzung)
(8) User / Admin / Superuser
Teil 4
(8) User / Admin / Superuser (Fortsetzung)
(9) Wie komme ich zu UNIX-Programmen?
Teil 5
(9) Wie komme ich zu UNIX-Programmen? (Fortsetzung)
Teil 6
(10) Einige Unterschiede zwischen Darwin und anderen UNICES
(11) Weitere Informationen / Referenzen / Links
Dank
-------------
(5) I/O-Redirection / Pipes und Wildcards / Regular Expressions
Info: Diese beiden Dinge schaut man sich besser mit frischem Kopf an

(5.1) I/O-Redirection und Pipes
Generell verarbeiten Computerprogramme Daten. Dazu werden Eingaben benutzt und das Resultat ausgegeben. Ein Programm hat grundsätzlich folgende Eingabemöglichkeiten:
- eine Datei (Dateiname typischerweise in den Parametern angegeben)
- Benutzereingaben vom Terminal
Daneben bestehen foldende Ausgabemöglichkeiten:
- eine Datei (Dateiname typischerweise in den Parametern angegeben)
- Ausgabe am Terminal
- Fehlerausgabe am Terminal / Log-Datei
(5.1.1) I/O Redirection
Die standardmässig im Programm angewandten Ein- und Ausgabekanäle (stdIn, stdOut, stdError) sind zwar meist auf das Terminal gerichtet, können jedoch gelegentlich auch auf Dateien gerichtet sein. Diese Standard-Kanäle können einfach umgeleitet werden.
Beispiel: Schauen wir uns nochmals das aktuelle Verzeichnis an:
$ ls -l
Wir können diese lange Liste auch in eine Datei umleiten, so dass wir später noch damit arbeiten können. Wir benutzen dazu
$ ls -l >~/dummy_test_liste.txt
> leitet die Standardausgabe in die direkt dahinter angegebene Datei um.
Wichtig: Mit dieser Methode wird eine neue Datei begonnen. Wenn vorher schon eine Datei mit gleichem Namen bestand, so wird sie damit einfach überschrieben! Dies geschieht ohne Nachfrage bei Dir, ob Dir das recht ist (nur so als Info...).
Alternativ kann das Symbol >> anstelle von > verwendet werden. Dann wird die Datei nicht gelöscht, sondern der neue Inhalt an den alten Inhalt hinten angefügt. Dies eignet sich insbesondere zur Ergänzung einer Protokolldatei.
Wir können nun mit dieser Datei arbeiten. Am einfachsten schauen wir sie uns einfach mal an.:
$ less ~/dummy_test_liste.txt
Wir können auch die Anzahl der Zeilen ansehen (siehe man wc, wie immer

$ wc -l ~/dummy_test_liste.txt
Das umgekehrte zur Umleitung der Ausgabe (>) ist die Umleitung der Eingabe mittels <. Als Beispiel zeigen wir, dass less nicht nur eine Datei benutzerfreundlich anzeigen kann, sondern auch Daten aus der Standardeingabe. Dies macht im Moment nicht sehr viel Sinn. Später werden wir den Sinn dahinter dann begreifen.
$ less <~/dummy_test_liste.txt
(5.1.2) Pipes
Wie bereits erwähnt, beruht eines der Konzepte in UNIX darin, Probleme nicht mit grossen Programmen zu lösen, sondern kleine, jedoch stabile und an Optionen mächtige Mini-Programme zB. in Scripts zusammenzufassen. Ein Teil dieses Konzepts sind Verbindungskanäle (Pipes), die es erlauben, die Ausgabe eines Programms direkt als Eingabe für ein anderes zu verwenden. Du kannst Dir dabei vorstellen, dass die Umleitung in eine Datei mittels > und das Einlesen dieser Information mittels < in einem Schritt zusammengefasst wird. Man benutzt dazu das Symbol |. Das coole an diesem Konzept ist, dass man sich diese Zwischendatei sogar sparen kann, wenn man sie später nicht sonst noch für eine Aufgabe benötigt.
Benutzen wir als Beispiel nochmals
$ ls -l
Wir sehen eine lange Liste an Dateien. Auf unserem modernen Terminal können wir bequem hunderte Zeilen nach oben scrollen. Dies war auf alten Konsolen mit fixierter Zeilenzahl nicht möglich, so dass man oft darauf angewiesen war, die Informationen auf Seiten aufteilen zu lassen (die verwendeten Programme nannte man Pager: more, less). less haben wir ja bereits mehrfach benutzt. Unter anderem wird es ja auch von man benutzt. Lassen wir uns also die lange Dateiliste seitenweise darstellen:
$ ls -l | less
Dabei können wir in less auf alle Funktionen zurückgreifen. Wir können neben dem Blättern auch die Suchfunktion benutzen, wie wir das in Teil 1 bereits gesehen haben.
Wir können uns so einfach auch die Anzahl der Zeilen ausgeben lassen (wie bereits oben mit dem Umweg über die Datei):
$ ls -l | wc -l
Achtung: Da ls -l als erste Zeile eine Informationszeile ausgibt, erhalten wir so zwar die Anzahl der Zeilen, jedoch nicht die Anzahl der Dateien. Tja, in UNIX nimmt man's genau

Deshalb eignet sich folgender Befehl zur Eruierung der Anzahl der Dateien:
$ ls -1 | wc -l (Als Option bei ls eine 1 [eins] anstelle von l [kleines L], die Option für wc bleibt ein kleines L)
ls -1 (eins) gibt ganz brav eine Datei pro Zeile aus. Dabei werden keine zusätzlichen Informationen wie bei ls -l (kleines L) ausgegeben. Diese brauchen wir nur zum zählen auch nicht. Ausserdem werden weniger Rechenressourcen verbraucht. (Nebenbei: Im Kontext von Pipes kann man sich den Parameter -1 [eins] bei ls auch sparen, da er dann standardmässig benutzt wird: Man kann also anstelle von ls -1 | wc -l auch kurz ls | wc -l verwenden.)
Für unser nächstes Beispiel benutzen wir eine weiteres Programm grep. Dies ist ein sehr mächtiges Programm, mit dem sich innerhalb einer Datei Zeilen suchen lassen, die einem bestimmten Muster entsprechen (siehe regular expressions unten) in Dateien auswerten kann (Vorschlag: man grep

Beispiel: Wir suchen alle Kalendereinträge mit der Buchstaben-Kombination "LOTR" und sehen auf dem Bildschirm die zeitliche Abfolge einer berühmten "Kurzgeschichte".
$ grep "LOTR" /usr/share/calendar/calendar.history | less
(Jetzt bleibt nur noch das Problem, dass das Abenteuer im Dezember und nicht im Januar beginnt - doch das soll uns in unserer aktuellen technischen Betrachtung nicht stören)
Diese Umleitungen können noch weiter kombiniert werden. Auch kann die Fehlerausgabe ebenso umgeleitet werden: Einige Beispiele (Englisch)
Unser letztes Beispiel können wir nutzen, um die Dateien nach deren Grösse sortiert auszugeben (wir benutzen ls wieder mit der Option -l [kleines L]):
$ ls -l | sort -n +4 (kleinste Datei zuerst)
$ ls -l | sort -nr +4 (grösste Datei zuerst, reversed)
Wir können auch mal schauen, welches so die grössten Dateien unseres gesammten Benutzerverzeichnisses sind. Wir benutzen dabei eine Option -R (rekursiv) für ls. Dabei wird jedes passende Verzeichnis (mit der aktuellen Angabe alle) gleich nochmals zum durchsuchen verwendet.
Dieses Beispiel hier nur einmal zur Verdeutlichung, was so mittels pipes gemacht werden kann. Auch wissen wir dann, welches so unsere grossen Dateien sind:Warnschild schrieb:Warnung: Zahlreiche Programme bieten eine Option für eine rekursive Anwendung. Dabei ist äusserste Vorsicht geboten. Man hat schneller unbedacht ganze Dateien vernichtet, als einem lieb ist.
$ ls -lR ~ | sort -nr +4 | less
Erklärung: ls generiert von unserem Benutzerverzeichnis ~ eine ausführliche Liste. Dabei wird es rekursiv auch auf Unterverzeichnisse angewandt. sort sortiert uns das ganze rückwärts nach der Dateigrösse (Spalte 5). less präsentiert uns das ganze geordnet auf dem Bildschirm.
(5.2) Wildcards und Regular Expressions
(5.2.1) Wildcards
Manchmal wünscht man einen Befehl nicht nur auf eine ganz genau definierte Datei anzuwenden, sondern auf alle Dateien, deren Namen gewissen Vorgaben enspricht. Dazu kann man in der Shell die Platzhalter * und ? (Wildcards genannt) einsetzen.
? bedeutet dabei genau ein Zeichen (1)
* bedeutet dabei keines, eines oder mehrere Zeichen (0 - n)
Beispiele:
*.jpg --> alle Dateien, die mit .jpg aufhören
*.doc --> alle Word-Dateien
* --> alle nicht-versteckten Dateien
So zeigt uns folgender Befehl alle JPG-Dateien des aktuellen Verzeichnisses an
$ ls *.jpg
Wichtig: Gerade die Anwendung von Wildcards kann teilweise unbeabsichtigte Effekte haben, wenn nicht peinlich auf die korrekte Schreibweise geachet wird. So darf beispielsweise kein Leerzeichen zwischen * und dem Rest sein, da sonst beide Elemente als separate Parameter interpretiert werden mit entsprechenden Konsequenzen. Bei ls kann dies mal zu einer komischen Ansicht führen. Bei rm, mv oder cp können die Folgen rasch verheerend sein!!!
Weiteres Beispiel: Zur Suche von bestimmten Dateien auch innerhalb der Unterverzeichnisse bietet sich das Programm find an (man find, wie immer

$ find ~ -name "*.jpg" | less
Dieser Befehll istet uns in gewohnter auf die Seitengrösse zugeschnittener Art alle Dateien mit der Endung .jpg auf. Es gibt jedoch auch JPEG-Dateien, welche die Endung jpeg haben.
Wenn wir gleichzeitig nach .jpg und .jpeg suchen wollen, so erreichen wir dies mit einer Verknüpfung zweier Suchparameter mittels logischem ODER (Parameter –or bzw. –o):
$ find ~ -name "*.jpg" -or -name "*.jpeg" | less
Et voilà! So einfach ist das

(5.2.2) Regular Expressions
Neben den Wildcards bieten einige Programme noch die Möglichkeit an, reguläre Ausdrücke (regular expressions, regex) zur Definition eines Suchausdruckes zu verwenden. Wir haben von diese Programmen bereits grep, less und man kennengelernt. Auch bash unterstützt regex in Scripts, jedoch nicht allgemein für alle Programme im interaktiven Modus.
Es ist wichtig, regex von Grund auf zu lernen, so dass sich nicht unnötige Fehler einschleichen. Einen Start in die Welt der regex bieten die Links des Wikipedia-Artikels (deutsch, oder noch besser englisch). Anbei nur ganz kurz wichtige Unterschiede einiger in Wildcards und regex verwendeter Zeichen:
In regex beschreiben ? und * wieder die Anzahl der Elemente. Jedoch bezieht sich diese Quantität auf das Element, welches direkt davor steht. Auch kann ? der Quantität 0 entsprechen. Daneben ist vor allem wichtig, dass der Punkt eine funktionelle Bedeutung hat (irgend ein Zeichen). Wenn wir also verlangen, dass ein Punkt im Text vorkommen muss, so muss der Punkt speziell markiert (escape) werden: Ein Punkt wird als \. Geschrieben. Genauso müsen auch zahlreiche andere zeichen (zB. runde, eckige und geschweifte Klammern) escaped werden, wenn man nach ihnen als Zeichen suchen lassen will. So können die von der Shell bekannte Wildcard * folgendermassen in einer regex angegeben werden: .*
Beispiel: Selbstverständlich bietet auch find die Möglichkeit regex zu verwenden. Die oben angegebene Suche nach .jpg und .jpeg können wir beispielsweise wie folgt auch so formulieren:
$ find -E ~ -regex "^.*\.jp[e]?g" | less
Erklärung: Wir benutzen find mit der Option –E (erweiterte regex) für unser Verzeichnis ~. Den regulären Ausdruck platzieren wir hinter –regex. ^ verweist auf den Zeilenanfang. .* erlaubt eine beliebige Anzahl Zeichen vor dem Punkt \. (escaped!). Dann kommt unser Suffix: Es soll genau .jpg oder .jpeg lauten. Das Fragezeichen erlaubt wie oben erwähnt im Gegensatz zur Wildcard auch die Möglichkeit der Quantität 0 des definierten Zeichens e.
Alternativ kann man auch einen Suchausdruck verwenden, der das ganze vom Zeilenende ($) her definiert:
$ find -E ~ -regex ".*\.jp[e]?g$" | less
Wir sehen schon: Regex sind ausserordentlich hilfreich, insbesondere sie auch in verschiedenen Programmiersprachen verwendet werden können – obwohl es teilweise halt gewisse Unterschiede in den Details gibt.
Vorsicht: Auch regex bringen ein riesiges Fehlerpotential mit sich. So ist eine gute Dokumentation der Funktion unerlässlich. Oftmals ist diese deutlich länger als eine oft kryptisch aussehender regulärer Ausdruck.
(6) Editoren vi/vim, Emacs und nano
Editoren sind der Schlüssel zur Konfiguration von Unix. Alle Konfigurationsdateien sind in lesbarem Text gespeichert. Formal handelt es sich bei dem, was wir im Alltag als Editor bezichnen um "interaktive Text-Editoren", also um Programme, mit deren Hilfe wir selbst Texte interaktiv ändern können. Daneben gibt es noch eine Vielzahl anderer nicht-interaktiver Editoren, auf die wir hier nicht eingehen (Bsp: awk, sed, groff).
vi ist ein ausserordentlich mächtiges Werkzeug, er erschlägt den Neuling jedoch aufgrund der Vielzahl an Optionen. Er hat jedoch klar seine Bedeutung, da er standardmässig wohl auf jedem UNIX-System installiert ist und auch andere Programme darauf standardmässig zugreifen (zB. visudo). Selbstverständlich erlaubt die Suchfunktion ebenso reguläre Ausdrücke.
Darwin bringt die Weiterentwicklung vim mit. Die Dokumentation ist sehr umfangreich (Kurzanleitung).
Hier nur die wichtigste Kommandofolge: Wie komme ich aus dem Programm raus, ohne die Datei zu verändern: Link (die Tropfen, die Du nun auf dem Bildschirm siehst, sind meine Schweisstropfen, die sich mal bildeten, als ich eine Systemdatei als root mal mit vim anschauen wollte...).
Nun: Es geht auch frei von Angstschweiss: Für vi bietet Darwin ein eigenes interaktives Tutorial (Dauer ca. 30 Minuten). Viel Vergnügen:
$ vimtutor de (sogar in deutsch)
Ähnlich ist auch der Emacs eine Welt für sich. Man kann ihn sogar für Spiele benutzen.
Für den Einstig wesentlich praktischer ist ein kompakter Editor nano (siehe auch man nano). Wir schauen ihn kurz an, da wir ihn ihn der Folge benutzen werden
$ nano ~/irgendeine_datei.txt
--> Bildschirm mit Editierfähigkeit wie wir das von üblichen Editoren des Mac OS kennen. Er bietet den Vorteil, dass er seine wichtigen Befehle unten anzeigt, so dass er wirklich einfach zu benutzen ist.
Geben wir mal irgend einen Text ein.
Wir beenden ihn mit ctrl-x. Dabei fragt er automatisch, ob wir die Datei speichern wollen. y (yes) zum Speichern, n (no) zum Verwerfen des Textes. Nachdem wir yes gewählt haben, fragt er nochmals nach dem Dateinamen, den wir einfach mit der Return-Taste bestätigen können. Ganz einfach, ohne Schweisstropfen auf der Stirn

nano ist wirklich nur ein simpler Editor (für den raschen Start). Wer sich länger mit UNIX beschäftigt, lernt besser vi zu benutzen. Neben seinem Funktionsumfang gehört seine praktisch uneingeschränkte Verfügbarkeit auf praktisch jedem UNIX/Linux zu seinen Stärken. Ich erinnere nochmals an:
$ vimtutor de
(7) "Pimp my Terminal"
(7.1) Programm Terminal.app
Aufmerksame Leser haben es mittlerweile sicher bereits realisiert. Terminal selbst ist "nur" ein Programm, das die Eingabe und Ausgabe von Text ermöglicht. Damit wird eine Konsole (Bildschirm und Tastatur) simuliert. Diese Daten werden dann einer Shell nach eigener Wahl zur Verfügung gestellt. Wir erinnern uns: Zu Zeiten der Grossrechner hatte der Benutzer nur ein "dummes" Text-Eingabe-Gerät (Konsole, Terminal), welches über eine direkte Kabelverbindung oder prinzipiell unabhängig davon über eine längere geschützte Datenleitung mit dem Zentralrechner verbunden war. Auf diesem Rechner lief dann das Programm sh oder ein späteres Derivat.
So sehen wir, dass Terminal.app neben dem Standard 'neues Shell-Fenster' auf dem eigenen Computer auch die Möglichkeit bietet, sich auf einem anderen Server einzuloggen (Telnet uncodiert [davon ist abzuraten] oder SSH codiert; ein cooles Tutorial dazu gibt es von Cyrics). Abgesehen davon, dass das Ganze wegen der Datenkommunikation langsamer läuft, ist die Bedienung identisch. Auch muss man dieselbe Vorsicht walten lassen: Man kann auch auf Distanz einen Computer auseinander nehmen...
Das Terminal-Programm kann im Aussehen angepasst werden. Standardmässig hat es in der aktuellen Version in Tiger schwarze Zeichen (Font Monaco) vor einem weissen Hintergrund. Dazu dienen folgende Menüs:
Terminal --> Einstellungen (Auswahl der Shell möglich; ich würde daran nur etwas ändern, wenn ich genau weiss, was zu tun ist).
Terminal --> Fenstereinstellungen
- Shell: Einstellungen, ob das Fenster nach Prozessende offen bleiben soll
- Prozesse: Wie soll bei bestimmten laufenden Prozessen vorgegangen werden (für Fortgeschrittene)
- Emulation: Da kann man sich das Leben härter (praktisch originale Emulation zu früheren Terminals) oder einfacher machen (praktische Zusatzfunktionen aktivieren, beispielsweise auch copy & paste)
- Puffer: Ist ebenso selbsterklärend. Wir profitieren jedoch schon davon, dass unsere Computer mehr als die früher standardmässigen 80x24 Zeichen darstellen und sich merken können (siehe Scroll-Funktion im Terminal-Fenster). Früher musste man viel öfter von Pipes und Programmen wie more oder less Gebrauch machen (and by the way: less is more
).
- Darstellung: Scheint auch selbsterklärend. Bei Zeichensatz-Einstellung empfehle ich UTF-8 (darauf kommen wir noch bei der Shell zu sprechen). Wichtig: Als Schriftart soll nur eine nicht-proportionale Schriftart (Monaco, Courier, Courier New, Andale Mono, American Typewriter) verwendet werden. Terminals können nichts mit modernen proportionalen Schriftarten anfangen (falsche Darstellung!). Text glätten (Anti-Aliasing) ist erst bei grösseren Schriftarten praktikabel.
- Farbe: Hier kann man vom modernen Schwarz auf Weiss auf ein traditionelleres Weiss/Grau auf Schwarz oder noch besser Grün/Schwarz oder Bernsteinfarben/Schwarz wechseln. Da kommt noch "echteres" Konsolen-Feeling auf... Selbstverständlich kann man so auch Terminals mit bestimmten Funktionen definierten Farben zuordnen.
- Fenster: Hier kann man die Fenstergrösse anpassen und eigene Startbefehle definieren. Klassisch ist jedoch die Grösse 80x24
- Tastatur: Auch hier kann man mehr einstellen, als früher möglich war
(7.2) Shells
Die Benutzereingaben werden durch einen Kommandozeileninterpreter, eine sogenannte Shell verarbeitet und dann die entsprechenden Programme ausgeführt. Die Thompson-Shell (osh) war die erste UNIX-Standard-Shell. Die später entwickelte Bourne Shell sh ist sozusagen der Vorfahre der meisten heute gebräuchlichen Shells. Diese später entstandene Derivate boten besseren Bedienkomfort oder zusätzliche Funktionen. Kurz die wichtigsten vorgestellt:
- bash: Bourn Again Shell (Wortspiel zur Bourne Shell). Häufigste in Linux-Systemen verwendete Shell. Standardshell für Mac OS ab Panther. Sie ist abwärts-kompatibel zu sh.
- csh: Hauptsächlicher Unterschied der Scriptsprache, die eigentlich auf der Programmiersprache C beruht. Deshalb ist sie nicht kompatibel zu sh oder eben bash. Kaum editierfähig.
- tcsh: Erweiterte csh. Sehr komfortabel in der Bedienung. War bis 10.2 die Standardshell von Mac OS X.
- ksh: Korn Shell. War in vielen kommerziellen UNICES. Ist ebenso in Mac OS dabei.
- zsh: Ausserordentlich leistungsfähige Shell, praktisch vollständig kompatibel zu bash, tcsh und ksh. Auch in Mac OS enthalten. Lohnt sich wohl etwas genauer anzusehen (für Fortgeschrittene).
Link: Fortsetzung Teil 3
Zuletzt bearbeitet von einem Moderator: