Linux Professional Institute Learning Logo.
Weiter zum Inhalt
  • Home
    • Alle Ressourcen
    • LPI Lernmaterialien
    • Mitmachen
    • Publishing Partner
    • Publishing Partner werden
    • Über uns
    • FAQ
    • Mitwirkende
    • Roadmap
    • Kontakt
  • LPI.org
103.4 Lektion 2
Thema 101: Systemarchitektur
101.1 Hardwareeinstellungen ermitteln und konfigurieren
  • 101.1 Lektion 1
101.2 Das System starten
  • 101.2 Lektion 1
101.3 Runlevel wechseln und das System anhalten oder neu starten
  • 101.3 Lektion 1
Thema 102: Linux-Installation und -Paketverwaltung
102.1 Festplattenaufteilung planen
  • 102.1 Lektion 1
102.2 Einen Bootmanager installieren
  • 102.2 Lektion 1
102.3 Shared Libraries verwalten
  • 102.3 Lektion 1
102.4 Debian-Paketverwaltung verwenden
  • 102.4 Lektion 1
102.5 RPM und YUM-Paketverwaltung verwenden
  • 102.5 Lektion 1
102.6 Linux als Virtualisierungs-Gast
  • 102.6 Lektion 1
Thema 103: GNU- und Unix-Befehle
103.1 Auf der Befehlszeile arbeiten
  • 103.1 Lektion 1
  • 103.1 Lektion 2
103.2 Textströme mit Filtern verarbeiten
  • 103.2 Lektion 1
103.3 Grundlegende Dateiverwaltung
  • 103.3 Lektion 1
  • 103.3 Lektion 2
103.4 Ströme, Pipes und Umleitungen verwenden
  • 103.4 Lektion 1
  • 103.4 Lektion 2
103.5 Prozesse erzeugen, überwachen und beenden
  • 103.5 Lektion 1
  • 103.5 Lektion 2
103.6 Prozess-Ausführungsprioritäten ändern
  • 103.6 Lektion 1
103.7 Textdateien mit regulären Ausdrücken durchsuchen
  • 103.7 Lektion 1
  • 103.7 Lektion 2
103.8 Grundlegendes Editieren von Dateien
  • 103.8 Lektion 1
Thema 104: Geräte, Linux-Dateisysteme, Filesystem Hierarchy Standard
104.1 Partitionen und Dateisysteme anlegen
  • 104.1 Lektion 1
104.2 Die Integrität von Dateisystemen sichern
  • 104.2 Lektion 1
104.3 Das Mounten und Unmounten von Dateisystemen steuern
  • 104.3 Lektion 1
104.5 Dateizugriffsrechte und -eigentümerschaft verwalten
  • 104.5 Lektion 1
104.6 Symbolische und Hardlinks anlegen und ändern
  • 104.6 Lektion 1
104.7 Systemdateien finden und Dateien am richtigen Ort plazieren
  • 104.7 Lektion 1
How to get certified
  1. Thema 103: GNU- und Unix-Befehle
  2. 103.4 Ströme, Pipes und Umleitungen verwenden
  3. 103.4 Lektion 2

103.4 Lektion 2

Zertifikat:

LPIC-1 (101)

Version:

5.0

Thema:

103 GNU- und Unix-Befehle

Lernziel:

103.4 Ströme, Pipes und Umleitungen verwenden

Lektion:

2 von 2

Einführung

Ein Aspekt der Unix-Philosophie besagt, dass jedes Programm einen spezifischen Zweck haben sollte und nicht versuchen sollte Funktionalitäten außerhalb seines Geltungsbereichs zu integrieren. Aber die Dinge einfach zu halten bedeutet nicht, dass die Ergebnisse weniger ausgefeilt sind, denn verschiedene Programme können miteinander verkettet werden, um ein kombiniertes Resultat zu erzeugen. Der senkrechte Strich |, auch als Pipesymbol bekannt, kann verwendet werden, um eine Pipeline zu erstellen, welche die Ausgabe eines Programms direkt mit der Eingabe eines anderen Programms verbindet, während Befehlssubstitution es erlaubt, die Ausgabe eines Programms in einer Variablen zu speichern oder diese direkt als Argument für einen anderen Befehl zu verwenden.

Pipes

Im Gegensatz zu Umleitungen fließen bei Pipes die Daten in der Befehlszeile von links nach rechts, und das Ziel ist ein anderer Prozess und nicht ein Dateisystempfad, ein Dateideskriptor oder ein Here-Dokument. Das Pipe-Symbol | weist die Shell an, alle verschiedenen Befehle gleichzeitig zu starten und die Ausgabe des vorhergehenden Befehls mit der Eingabe des folgenden Befehls von links nach rechts zu verbinden. Anstatt beispielsweise Umleitungen zu verwenden, kann der Inhalt der Datei /proc/cpuinfo, die von cat an die Standardausgabe gesendet wird, mit dem folgenden Befehl an stdin von wc gepiped werden:

$ cat /proc/cpuinfo | wc
   208    1184    6096

Fehlt ein Pfad zu einer Datei, zählt wc die Anzahl der Zeilen, Wörter und Zeichen, die es auf seiner stdin erhält, wie es im obigen Beispiel der Fall ist. In einem zusammengesetzten Befehl können viele Pipes vorhanden sein. Im folgenden Beispiel werden zwei Pipes verwendet:

$ cat /proc/cpuinfo | grep 'model name' | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

Der Inhalt der Datei /proc/cpuinfo, die von cat /proc/cpuinfo erzeugt wird, wird an den Befehl grep 'model name' weitergeleitet, der dann nur die Zeilen ausgibt, welche den Begriff model name enthalten. Die Maschine, auf der das Beispiel läuft, hat viele CPUs, daher gibt es mehrfach Zeilen mit dem String model name. Die letzte Pipe verbindet grep 'model name' mit dem Befehl uniq, der dafür verantwortlich ist jede Zeile, die gleich der vorherigen ist, zu überspringen.

Pipes können mit Umleitungen in derselben Befehlszeile kombiniert werden. Das vorherige Beispiel kann in folgende vereinfachte Form umgeschrieben werden:

$ grep 'model name' </proc/cpuinfo | uniq
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

Die Eingabeumleitung für grep ist nicht unbedingt notwendig, da grep einen Dateipfad als Argument akzeptiert, aber das Beispiel zeigt, wie solche kombinierten Befehle erstellt werden können.

Pipes und Weiterleitungen sind exklusiv, d.h. eine Quelle kann nur einem Ziel zugeordnet werden. Es ist jedoch möglich, eine Ausgabe in eine Datei umzuleiten und diese trotzdem mit dem Programm tee auf dem Bildschirm anzuzeigen. Dazu sendet das erste Programm seine Ausgabe an stdin von tee. Zum Speichern der Daten wird tee zusätzlich noch ein Dateiname übergeben:

$ grep 'model name' </proc/cpuinfo | uniq | tee cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz
$ cat cpu_model.txt
model name      : Intel(R) Xeon(R) CPU           X5355  @ 2.66GHz

Die Ausgabe des letzten Programms in der Kette, die von uniq erzeugt wurde, wird angezeigt und in der Datei cpu_model.txt gespeichert. Um den Inhalt der bereitgestellten Datei nicht zu überschreiben, sondern Daten an diese anzuhängen, muß tee mit der Option -a kombiniert werden.

Nur die Standardausgabe eines Prozesses wird durch eine Pipe erfasst. Nehmen wir an, Sie müssen einen langwierigen Kompilierungsprozess auf dem Bildschirm durchlaufen und gleichzeitig sowohl die Standardausgabe als auch den Standardfehler in einer Datei zur späteren Überprüfung speichern. Angenommen Ihr aktuelles Verzeichnis hat kein Makefile, dann wird der folgende Befehl einen Fehler verursachen:

$ make | tee log.txt
make: *** No targets specified and no makefile found.  Stop.

Obwohl auf dem Bildschirm angezeigt, wurde die von make erzeugte Fehlermeldung nicht von tee erfasst und die Datei log.txt wurde zwar erstellt, blieb aber leer. Es muss eine Umleitung durchgeführt werden, bevor eine Pipe stderr erfassen kann:

$ make 2>&1 | tee log.txt
make: *** No targets specified and no makefile found.  Stop.
$ cat log.txt
make: *** No targets specified and no makefile found.  Stop.

In diesem Beispiel wurde stderr von make auf stdout umgeleitet, so dass tee in der Lage war, ihn mit der Pipe zu erfassen, auf dem Bildschirm anzuzeigen und in der Datei log.txt zu speichern. In Fällen wie diesem kann es nützlich sein, die Fehlermeldungen für eine spätere Überprüfung zu speichern.

Befehlssubstitution

Eine andere Methode zur Erfassung der Ausgabe eines Befehls ist die Befehlssubstitution. Indem ein Befehl in Anführungszeichen gesetzt wird, ersetzt die Bash ihn durch seine Standardausgabe. Das folgende Beispiel zeigt, wie stdout eines Programms als Argument für ein anderes Programm verwendet werden kann:

$ mkdir `date +%Y-%m-%d`
$ ls
2019-09-05

Die Ausgabe des Programms date, das aktuelle Datum formatiert als Jahr-Monat-Tag, wurde als Argument benutzt, um ein Verzeichnis mittels mkdir zu erstellen. Ein identisches Ergebnis erhält man durch die Verwendung von $() anstelle von Backquotes:

$ rmdir 2019-09-05
$ mkdir $(date +%Y-%m-%d)
$ ls
2019-09-05

Dieselbe Methode kann verwendet werden, um die Ausgabe eines Befehls als Variable zu speichern:

$ OS=`uname -o`
$ echo $OS
GNU/Linux

Der Befehl uname -o gibt den generischen Namen des aktuellen Betriebssystems aus, der in der Sessionvariablen OS gespeichert ist. Die Zuweisung der Ausgabe eines Befehls an eine Variable ist in Skripten sehr nützlich und ermöglicht es, die Daten auf viele verschiedene Arten zu speichern und auszuwerten.

Abhängig von der Ausgabe, die durch den ersetzten Befehl erzeugt wird, ist die eingebaute Befehlssubstitution möglicherweise nicht geeignet. Eine ausgefeiltere Methode, die Ausgabe eines Programms als Argument eines anderen Programms zu verwenden, benutzt eine Zwischenstufe namens xargs. Das Programm xargs verwendet den Inhalt, den es über stdin erhält, um einen bestimmten Befehl mit dem Inhalt als Argument auszuführen. Das folgende Beispiel zeigt, wie xargs das Programm identify mit den vom Programm find gelieferten Argumenten ausführt:

$ find /usr/share/icons -name 'debian*' | xargs identify -format "%f: %wx%h\n"
debian-swirl.svg: 48x48
debian-swirl.png: 22x22
debian-swirl.png: 32x32
debian-swirl.png: 256x256
debian-swirl.png: 48x48
debian-swirl.png: 16x16
debian-swirl.png: 24x24
debian-swirl.svg: 48x48

Das Programm identify ist Teil von ImageMagick, einem Satz von Kommandozeilentools zum Prüfen, Konvertieren und Bearbeiten der meisten Bilddateitypen. Im Beispiel nimmt xargs alle Pfade, die von find aufgelistet wurden, und setzt diese als Argumente für identify ein, das dann die Informationen für jede Datei anzeigt, die entsprechend der Option -format formatiert wurden. Die von find im Beispiel gefundenen Dateien sind Bilder, die das Logo der Distribution in einem Debiandateisystem enthalten. -format ist ein Parameter von identify, nicht von xargs.

Die Option -n 1 veranlasst xargs, den gegebenen Befehl mit nur einem Argument gleichzeitig auszuführen. Anstatt alle von find gefundenen Pfade als Liste von Argumenten für identify zu übergeben, würde im Fall des Beispiels die Verwendung von xargs -n 1 den Befehl identify für jeden Pfad einzeln ausführen. Die Verwendung von -n 2 würde den Befehl identify mit zwei Pfaden als Argument ausführen, -n 3 mit drei Pfaden als Argument und so weiter. In ähnlicher Weise kann bei der Verarbeitung mehrzeiliger Inhalte durch xargs — wie es bei der Eingabe durch find der Fall ist — die Option -L verwendet werden, um zu begrenzen, wie viele Zeilen als Argumente pro Befehlsausführung verwendet werden.

Note

Die Verwendung von xargs mit der Option -n 1 oder -L 1 zur Verarbeitung der von find erzeugten Ausgabe, kann unnötig sein. Das Kommando find hat die Option -exec, um ein gegebenes Kommando für jedes Suchergebniselement auszuführen.

Wenn die Pfade Leerzeichen enthalten, ist es wichtig, find mit der Option -print0 auszuführen. Diese Option weist find an, ein Null-Zeichen zwischen jedem Eintrag zu verwenden, damit die Liste von xargs korrekt geparst werden kann (die Ausgabe wurde unterdrückt):

$ find . -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 du | sort -n

Die Option -0 weist xargs an, dass das Null-Zeichen als Trennzeichen verwendet werden soll. Auf diese Weise werden die von find angegebenen Dateipfade korrekt geparst, auch wenn diese Leer- oder andere Sonderzeichen enthalten. Das vorherige Beispiel zeigt, wie man den Befehl du benutzt, um die Plattennutzung jeder gefundenen Datei herauszufinden und dann die Ergebnisse nach Größe zu sortieren. Die Ausgabe wurde aus Gründen der Übersichtlichkeit vernachlässigt. Beachten Sie, dass es für jedes Suchkriterium notwendig ist, die Option -print0 für find zu benutzen.

Standardmäßig setzt xargs die Argumente des ausgeführten Befehls an die letzte Stelle. Um dieses Verhalten zu ändern, kann die Option -I verwendet werden:

$ find . -mindepth 2 -name '*avi' -print0 -o -name '*mp4' -print0 -o -name '*mkv' -print0 | xargs -0 -I PATH mv PATH ./

Im letzten Beispiel wird jede von find gefundene Datei in das aktuelle Verzeichnis verschoben. Da der/die Quellpfad(e) mv vor dem Zielpfad mitgeteilt werden muß/müssen, wird der Option -I von xargs ein Ersatzbegriff übergeben, der dann entsprechend neben mv gesetzt wird. Durch die Verwendung des Null-Zeichens als Trennzeichen ist es nicht notwendig, den Substitutionsterm in Anführungszeichen zu setzen.

Geführte Übungen

  1. Es ist üblich das Ausführungsdatum von Aktionen zu speichern, die von automatisierten Skripten ausgeführt werden. Der Befehl date +%Y-%m-%d zeigt das aktuelle Datum im Format Jahr-Monat-Tag. Wie kann die Ausgabe eines solchen Befehls mittels Befehlssubstitution in einer Shellvariablen namens TODAY gespeichert werden?

  2. Wie kann der Inhalt der Variablen TODAY mittels des Befehls echo an die Standardeingabe des Befehls sed s/-/./g übergeben werden?

  3. Wie könnte die Ausgabe des Befehls date +%Y-%m-%d als Here-String verwendet werden, um sed s/-/./g zu instruieren?

  4. Der Befehl convert image.jpeg -resize 25% small/image.jpeg erzeugt eine kleinere Version von image.jpeg und legt das resultierende Bild in einer gleichnamigen Datei des Unterverzeichnis small ab. Wie ist es mit xargs möglich, für jedes in der Datei filelist.txt aufgeführte Bild den gleichen Befehl auszuführen?

Offene Übungen

  1. Eine einfache Sicherungsroutine erstellt periodisch ein Abbild der Partition /dev/sda1 mittels dd < /dev/sda1 > sda1.img. Um zukünftige Datenintegritätsprüfungen durchzuführen, erzeugt die Routine auch einen SHA1-Hash der Datei mittels sha1sum < sda1.img > sda1.sha1. Wie würden diese beiden Befehle durch Hinzufügen von Pipes und dem Befehl tee zu einem Einzigen kombiniert werden?

  2. Der Befehl tar wird verwendet, um viele Dateien in einer einzigen Datei zu archivieren, wobei die Verzeichnisstruktur erhalten bleibt. Die Option -T erlaubt es, eine Datei anzugeben, welche die zu archivierenden Pfade enthält. Zum Beispiel erzeugt find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - eine komprimierte Datei im Format von tar namens etc.tar.xz aus der durch den Befehl find bereitgestellten Liste (Option -T - gibt die Standardeingabe als Pfadliste an). Um mögliche Parsingfehler aufgrund von Pfaden, die Leerzeichen enthalten, zu vermeiden, sollten welche Befehlsoptionen für find und tar genutzt sein?

  3. Anstatt eine neue Remoteshellsitzung zu eröffnen, kann der Befehl ssh einfach einen Befehl ausführen, der als Argument angegeben wird: ssh user@storage "remote command". Da ssh auch erlaubt die Standardausgabe eines lokalen Programms auf die Standardeingabe des entfernten Programms umzuleiten, wie würde der Befehl cat eine lokale Datei mit dem Namen etc.tar.gz an /srv/backup/etc.tar.gz unter user@storage durch ssh umleiten?

Zusammenfassung

Diese Lektion behandelt traditionelle Interprozesskommunikationstechniken, die von Linux verwendet werden. Befehlspipelining erzeugt einen Einwegkommunikationskanal zwischen zwei Prozessen und Befehlssubstitution erlaubt es, die Ausgabe eines Prozesses in einer Shellvariablen zu speichern. Die Lektion behandelt folgenden Punkte:

  • Wie Pipes verwendet werden können, um den Output eines Prozesses an den Input eines anderen Prozesses zu streamen.

  • Der Zweck der Befehle tee und xargs.

  • Erfassung von Prozessausgaben mittels Befehlssubstitution, Speicherung dieser in Variablen oder Verwendung dieser direkt als Parameter für einen anderen Befehl.

Die behandelten Befehle und Verfahren lauten:

  • Pipelines benutzen mittels |.

  • Befehlssubstitution mit Backticks und $().

  • Die Befehle tee, xargs und find.

Lösungen zu den geführten Übungen

  1. Es ist üblich das Ausführungsdatum von Aktionen zu speichern, die von automatisierten Skripten ausgeführt werden. Der Befehl date +%Y-%m-%d zeigt das aktuelle Datum im Format Jahr-Monat-Tag. Wie kann die Ausgabe eines solchen Befehls mittels Befehlssubstitution in einer Shellvariablen namens TODAY gespeichert werden?

    $ TODAY=`date +%Y-%m-%d`

    oder

    $ TODAY=$(date +%Y-%m-%d)
  2. Wie kann der Inhalt der Variablen TODAY mittels des Befehls echo an die Standardeingabe des Befehls sed s/-/./g übergeben werden?

    $ echo $TODAY | sed s/-/./g
  3. Wie könnte die Ausgabe des Befehls date +%Y-%m-%d als Here-String verwendet werden, um sed s/-/./g zu instruieren?

    $ sed s/-/./g <<< `date +%Y-%m-%d`

    oder

    $ sed s/-/./g <<< $(date +%Y-%m-%d)
  4. Der Befehl convert image.jpeg -resize 25% small/image.jpeg erzeugt eine kleinere Version von image.jpeg und legt das resultierende Bild in einer gleichnamigen Datei des Unterverzeichnis small ab. Wie ist es mit xargs möglich, für jedes in der Datei filelist.txt aufgeführte Bild den gleichen Befehl auszuführen?

    $ xargs -I IMG convert IMG -resize 25% small/IMG < filelist.txt

    oder

    $ cat filelist.txt | xargs -I IMG convert IMG -resize 25% small/IMG

Lösungen zu den offenen Übungen

  1. Eine einfache Sicherungsroutine erstellt periodisch ein Abbild der Partition /dev/sda1 mittels dd < /dev/sda1 > sda1.img. Um zukünftige Datenintegritätsprüfungen durchzuführen, erzeugt die Routine auch einen SHA1-Hash der Datei mittels sha1sum < sda1.img > sda1.sha1. Wie würden diese beiden Befehle durch Hinzufügen von Pipes und dem Befehl tee zu einem Einzigen kombiniert werden?

    # dd < /dev/sda1 | tee sda1.img | sha1sum > sda1.sha1
  2. Der Befehl tar wird verwendet, um viele Dateien in einer einzigen Datei zu archivieren, wobei die Verzeichnisstruktur erhalten bleibt. Die Option -T erlaubt es, eine Datei anzugeben, welche die zu archivierenden Pfade enthält. Zum Beispiel erzeugt find /etc -type f | tar -cJ -f /srv/backup/etc.tar.xz -T - eine komprimierte Datei im Format von tar namens etc.tar.xz aus der durch den Befehl find bereitgestellten Liste (Option -T - gibt die Standardeingabe als Pfadliste an). Um mögliche Parsingfehler aufgrund von Pfaden, die Leerzeichen enthalten, zu vermeiden, sollten welche Befehlsoptionen für find und tar genutzt sein?

    Options -print0 und --null:

    $ find /etc -type f -print0 | tar -cJ -f /srv/backup/etc.tar.xz --null -T -
  3. Anstatt eine neue Remote-Shell-Sitzung zu eröffnen, kann der Befehl ssh einfach einen Befehl ausführen, der als sein Argument angegeben ist: ssh user@storage "remote command". Da ssh auch erlaubt die Standardausgabe eines lokalen Programms auf die Standardeingabe des entfernten Programms umzuleiten, wie würde das cat eine lokale Datei mit dem Namen etc.tar.gz über die Pipe an /srv/backup/etc.tar.gz unter user@storage durch ssh weiterleiten?

    $ cat etc.tar.gz | ssh user@storage "cat > /srv/backup/etc.tar.gz"

    oder

    $ ssh user@storage "cat > /srv/backup/etc.tar.gz" < etc.tar.gz

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

Nächste Lektion

103.5 Prozesse erzeugen, überwachen und beenden (103.5 Lektion 1)

Nächste Lektion lesen

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

LPI ist eine Non-Profit-Organisation.

© 2023 Linux Professional Institute (LPI) ist eine globale Organisation für Zertifizierungsstandards und zur Karriereplanung für Open-Source-Profis. Mit mehr als 200.000 Zertifikatsinhabern ist es die weltweit erste und größte herstellerneutrale Linux- und Open-Source-Zertifizierungsstelle. LPI verfügt über zertifizierte Fachleute in über 180 Ländern, bietet Prüfungen in mehreren Sprachen an und hat Hunderte von Trainingspartnern.

Unser Ziel ist es, wirtschaftliche und kreative Möglichkeiten für alle zu ermöglichen, indem wir Open-Source-Wissens- und Kompetenzzertifizierungen allgemein zugänglich machen.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Kontaktieren Sie uns
  • Datenschutz und Cookie-Richtlinien

Haben Sie einen Fehler entdeckt oder möchten Sie helfen, diese Seite zu verbessern? Lassen Sie es uns wissen.

© 1999–2023 The Linux Professional Institute Inc. Alle Rechte vorbehalten.