Einführung in die Shell – Teil 3

Aus EasyLinux 03/2010

Einführung in die Shell – Teil 3

Starke Argumente

In den ersten zwei Teilen der Shell-Einführung [1,2] haben wir Sie mit den Grundlagen der Shell vertraut gemacht. Jetzt stellen wir einige Spezialtools vor, mit denen die Shell besonders leistungsfähig wird – darunter “xargs”.

In der letzten Ausgabe haben wir Ihnen am Ende des Guru-Trainings einen Befehl vorgestellt, mit dem Sie mehrere mit find gefundene PDF-Dateien gleichzeitig im Adobe Reader öffnen können – mit dem Versprechen, das genauer zu erklären. Der Befehl war:

find /tmp/ -name '*.pdf' -print0 | xargs -0 acroread

Er besteht aus zwei Kommandos, die über eine so genannte Pipe miteinander verbunden sind:

  • Das erste Kommando lautet find /tmp/ -name '*.pdf' -print0 und findet alle Dateien mit Endung .pdf, die im temporären Ordner /tmp/ oder einem seiner Unterverzeichnisse liegen. Die zusätzliche Option -print0 ist für den Zweck des anschließenden Adobe-Reader-Starts wichtig, denn Sie bewirkt, dass find in der Ausgabe nicht Leerzeichen oder Zeilenumbrüche, sondern ein spezielles Sonderzeichen zwischen die Dateinamen schreibt. Das hat den Vorteil, dass der gesamte Befehl auch dann funktioniert, wenn sich in einigen der Dateinamen Leerzeichen befinden.
  • Über das Pipe-Zeichen | wird die Ausgabe des ersten Kommandos (eine Liste von Dateinamen) zur Eingabe für das zweite Kommando. Es heißt xargs -0 acroread. Das Tool xargs ist besonders praktisch: Es wandelt Informationen aus der Standardeingabe in Argumente um. Die Wirkung können Sie leicht ausprobieren, indem Sie den Befehl ls / | xargs echo eingeben – ls / gibt den Inhalt des Wurzelverzeichnisses aus, und xargs macht aus dieser Ausgabe Argumente für den Befehl echo, der einfach seine Argumente ausgibt (siehe Kasten Ausgabe als Argumente). Die Option -0 (das ist eine Null, nicht der Großbuchstabe O) teilt xargs mit, dass es nicht normale Leerzeichen als Trenner für die verschiedenen Argumente interpretieren soll, sondern das Sonderzeichen, das find über die Option -print0 als Trenner eingefügt hat.

Die Regel ist: Wenn Sie find und xargs auf diese Weise kombinieren, müssen Sie entweder find mit der Option -print0 und xargs mit der Option -0 verwenden oder bei beiden Kommandos auf die Optionen verzichten – anderenfalls passen Ausgabe und Eingabe nicht zusammen, und xargs “versteht” Sie nicht.

Ausgabe als Argumente

Das folgende Kommando gibt den Inhalt des Wurzelverzeichnisses aus, setzt aber noch die Worte “Inhalt Wurzelverzeichnis:” vor die Ausgabe.

$ ls / | xargs echo "Inhalt Wurzelverzeichnis:"
Inhalt Wurzelverzeichnis: bin boot dev etc home lib lost+found media mnt opt proc root sbin srv sys tmp usr var

Das funktioniert in drei Schritten:

  • Das Kommando ls / listet den Inhalt des Wurzelverzeichnisses auf, gibt also z. B. bin boot dev etc home lib lost+found media mnt opt proc root sbin srv sys tmp usr var aus. Wenn Sie den Befehl alleine aufrufen, erscheinen diese Namen direkt in der Shell.
  • Über das Pipe-Zeichen reichen Sie die Ausgabe als Standardeingabe an das folgende Kommando weiter.
  • xargs echo "Inhalt Wurzelverzeichnis:" liest zunächst von der Standardeingabe. Es erhält dort die schon mehrfach gezeigte Liste von Verzeichnisnamen. Es baut dann ein neues Kommando zusammen, das sich aus echo "Inhalt Wurzelverzeichnis:" und der neuen Argumentliste zusammensetzt, so entsteht der Befehl echo "Inhalt Wurzelverzeichnis:" bin boot dev etc home lib lost+found media mnt opt proc root sbin srv sys tmp usr var. Diesen Befehl führt xargs dann aus.
  • Das Kommando echo weiß nichts von dem Umweg, auf dem es seine Argumente erhalten hat; es “sieht” einfach nur, dass es mit den Argumenten "Inhalt Wurzelverzeichnis:" bin boot dev etc home lib lost+found media mnt opt proc root sbin srv sys tmp usr var aufgerufen wurde, und gibt diesen Text aus.

Für Sammler: Umleitungen

Wollen Sie die Ausgabe eines Programms nicht (nur) im Terminalfenster sehen, sondern dauerhaft archivieren oder etwa für den Versand als E-Mail-Anhang in einer Datei sichern, nutzen Sie ein praktisches Feature der Shell: die Ausgabeumleitung. Dazu setzen Sie ganz am Schluss hinter das Kommando ein Größerzeichen (>) und einen Dateinamen: Die Ausgabe des Befehls landet in der Datei.

Jeder solche Aufruf mit > Dateiname löscht zunächst einen eventuell vorhandenen Inhalt der Datei und schreibt dann die Ausgabe hinein – so können Sie immer nur eine einzige Programmausgabe sichern. Soll eine Datei die Ergebnisse mehrerer Befehle enthalten, verwenden Sie statt > ein doppeltes Größer-Zeichen (>>): Dann hängt die Shell die Ausgabe an die Zieldatei an, ohne diese vorher zu leeren.

Beide Varianten können Sie auch kombinieren: Um etwa die Ausgaben von befehl1, befehl2 und befehl3 in der Datei /tmp/ausgaben.logzu protokollieren, geben Sie die Kommandos

befehl1 > /tmp/ausgaben.log
befehl2 >> /tmp/ausgaben.log
befehl3 >> /tmp/ausgaben.log

ein. Die erste Zeile sorgt über das einfache >-Zeichen zunächst dafür, dass die Zieldatei leer ist, bevor erste Informationen darin landen. Die zweiten und dritten Zeilen hängen dann die Ausgaben an die Datei an.

Beachten Sie, dass > und >> nur “normale” Ausgaben eines Befehls erfassen. Es gibt auch spezielle Fehlerausgaben, die aus Linux-Sicht über einen anderen “Kanal” laufen, die so genannte Standardfehlerausgabe (stderr). Entsprechend heißt die normale Ausgabe Standardausgabe (stdout). Erzeugt ein Programm neben den regulären Ausgaben auch Fehlermeldungen, bleiben diese weiterhin im Terminalfenster sichtbar und stehen nicht in der Zieldatei. Um auch die Fehler in der Datei zu protokollieren, passen Sie die Befehlszeile an und stellen vor das > bzw. >> ein kaufmännisches Und (&), insgesamt also: &> bzw. &>>. Liegt im aktuellen Arbeitsverzeichnis z. B. eine Datei mozilla.ps, aber keine Datei namens mozzzllla.ps, dann erzeugt der Befehl

ls -l mozilla.ps mozzzllla.ps &> /tmp/test.log

sowohl eine reguläre Ausgabe (Informationen über die Datei mozilla.ps) als auch eine Fehlerausgabe (über das Fehlen der anderen Datei). Beide Ausgaben landen nun dank der Umleitung mit &> in der Datei test.log, was Sie mit cat schnell überprüfen können:

esser@netbookhg:~$ cat /tmp/test.log
ls: Zugriff auf mozzzllla.ps nicht möglich: No such file or directory
-rw-r--r-- 1 esser esser 1482262 2010-02-07 00:22 mozilla.ps

Probieren Sie auch die Variante ohne das kaufmännische Und aus und vergleichen Sie die Ergebnisse.

Suchen und Ersetzen

Um in einer Datei konsequent das Wort “Apfel” durch “Birne” zu ersetzen, können Sie diese in einem Editor öffnen und dessen Ersetzenfunktion verwenden. Es geht aber auch auf der Shell, wenn Sie das Kommando sed verwenden. Dessen Syntax ist ein wenig gewöhnungsbedürftig, für einfache Aufgaben aber schnell gemeistert: Heißt Ihre Datei etwa test.txt, können Sie mit

sed -e s/Apfel/Birne/g test.txt > test2.txt

die Ersetzungen vornehmen. Die überarbeitete (Birnen-)Fassung landet dabei in der Datei test2.txt. Zur Erläuterung:

  • Die Option -e leitet einen Ausdruck (englisch: expression) ein, damit sagen Sie sed, was zu tun ist.
  • Der folgende Text s/Apfel/Birne/g ist ein solcher Ausdruck. Er beginnt mit einem Kommando (s, substitute = ersetzen), nach einem Schrägstrich folgt der zu ersetzende Begriff (Apfel), nach einem weiteren Schrägstrich der einzusetzende Text (Birne) und nach dem letzten Schrägstrich noch eine Option (g, global), welche dafür sorgt, dass sed auch mehrere Treffer in einer einzelnen Zeile ersetzt.
  • Es folgt als weiteres Argument der Name der Datei (test.txt),
  • und über die Umleitung > test2.txt schreiben Sie das Ergebnis der Ersetzung in die Datei test2.txt.

Dabei achtet sed genau auf die Unterschiede zwischen Groß- und Kleinschreibung – ein Vorkommen von “apfel” oder “aPFEL” würde das Kommando hier also ignorieren. Wortgrenzen spielen andererseits keine Rolle, aus “Apfelkompott” wird das grammatikalisch fehlerhafte “Birnekompott”, weil eben in “Apfelkompott” der gesuchte Begriff “Apfel” vorkommt.

Um auch andere Schreibweisen (“apfel”, “aPFEL” etc.) zu ersetzen, können Sie die zusätzliche Option i (ignore case, Groß-/Kleinschreibung ignorieren) verwenden, die Sie hinter der Option g ergänzen – der Befehl wird damit

sed -e s/Apfel/Birne/gi test.txt > test2.txt

Abbildung 1 zeigt eine Beispieldatei und das Produkt des obigen Kommandos, wobei die jeweiligen Vorkommen von “Apfel” oder “Birne” durch einen Aufruf von grep farblich hervorgehoben sind. Dort sehen Sie, dass sed nun unabhängig von Groß- und Kleinschreibung alle Äpfel im Text findet. Ersetzt wird dabei aber immer durch “Birne” in genau dieser Schreibweise – sed hätte keine Möglichkeit zu erahnen, dass Sie etwa “aPFEl” durch “bIRNe” ersetzen möchten.

Abbildung 1: Das Tool "sed" ersetzt Texte und kann auch Groß-/Kleinschreibung ignorieren.

Abbildung 1: Das Tool “sed” ersetzt Texte und kann auch Groß-/Kleinschreibung ignorieren.

Schnell sortiert

Die Ausgaben aller Shell-Kommandos können Sie mit dem Sortierprogramm sort in eine richtige Reihenfolge bringen. Dabei ist sort sehr mächtig und kommt auch mit der Aufgabe zurecht, komplexere tabellarische Ausgaben nach bestimmten Spalten zu sortieren. Ein einfacher sort-Aufruf sortiert alphanumerisch, also nach dem Alphabet, während sort -n nach Zahlen sortiert, also z. B. “1”, “2” und “11” in die richtige Reihenfolge bringt, während bei alphabetischer Sortierung die “11” zwischen “1” und “2” landet. Abbildung 2 zeigt ein Beispiel dafür.

Abbildung 2: Zeilen, die mit Zahlen beginnen, können Sie alphanumerisch ("sort") oder numerisch ("sort -n") sortieren.

Abbildung 2: Zeilen, die mit Zahlen beginnen, können Sie alphanumerisch (“sort”) oder numerisch (“sort -n”) sortieren.

Sie können sort direkt mit dem Namen einer zu sortierenden Datei als Argument aufrufen oder das Tool wieder in einer Pipeline einsetzen. So filten Sie beispielsweise aus einer großen Datei zunächst mit grep die interessanten Zeilen heraus und bringen diese anschließend mit sort in die richtige Reihenfolge:

$ grep München adressdatei.txt | sort
Amussen, Joseph, München, Hauptstraße 3
Meier, Martina, München, Isarweg 9
Roth, Karla, München, Postchaussee 17
Zülow, Anton, München, Nordpark 1

Sie könnten auch den umgekehrten Weg gehen (erst sortieren, dann filtern), aber das vergrößert die Antwortzeit, denn etwas zu sortieren, ist eine anspruchsvollere Aufgabe als, Dinge herausfiltern.

Tauchen in der Ausgabe mehrere identische Zeilen auf, können Sie sort dazu auffordern, diese “Doppler” zu entfernen. Dazu verwenden Sie die Option -u (unique, einmalig). Das funktioniert auch, wenn eine Datei bereits sortiert ist (und eventuell Doppler enthält) – dann ist es aber sinnvoller, statt sort das kleine Tool uniq zu verwenden, das von einer bereits sortierten Eingabe ausgeht und einfach alle doppelt oder öfter auftretenden Zeilen streicht.

Mehr Power als man denkt

Die Shell ist ein echtes Powertool: In unserer dreiteiligen Einführung haben wir Sie mit den Grundlagen vertraut gemacht und einige nützliche Tools vorgestellt. In jeder EasyLinux-Ausgabe finden Sie in den Shell-Tipps (in diesem Heft auf Seite 102) weitere Hinweise dazu, was auf der Shell alles möglich ist. Eine zusätzliche Fundgrube bietet das Archiv unserer Schwesterzeitschrift LinuxUser [3], dort gibt es vor allem in den älteren Artikeln der Rubrik “Zu Befehl” viele interessante Shell-Programm-Vorstellungen.

Haben Sie besondere Erwartungen an die Arbeit mit der Shell? Gibt es Aufgaben, die Sie gerne auf der Kommandozeile lösen würden, aber Sie kennen nicht den richtigen Weg? Dann schreiben Sie an die Redaktionsadresse – wir greifen Ihre Themenvorschläge gerne auf.

Infos

[1] Shell-Einführung, Teil 1: Hans-Georg Eßer, “Im Anfang war der Prompt”, EasyLinux 01/2010, S. 124 ff., https://www.linux-community.de/artikel/20197

[2] Shell-Einführung, Teil 2: Hans-Georg Eßer, “Hilfreiche Spezialisten”, EasyLinux 02/2010, S. 124 ff., https://www.linux-community.de/artikel/20420

[3] LinuxUser: http://www.linux-user.de/

EasyLinux 03/2010 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben