Pipeline (Unix)

Eine Pipeline von drei Programmprozessen, die an einem Textterminal ausgeführt werden

Im Unix-artig Computer Betriebssysteme, a Pipeline ist ein Mechanismus für Interprozesskommunikation Verwenden von Nachrichtenübergang. Eine Pipeline ist ein Satz von Prozesse mit ihren zusammengekettet Standardströme, damit der Ausgabetext jedes Prozesses (Stdout) wird direkt als Eingabe übergeben (Stdin) zum nächsten. Der zweite Prozess wird gestartet, wenn der erste Prozess noch ausgeführt wird und sie ausgeführt werden gleichzeitig. Das Konzept der Pipelines wurde von durchgesetzt von Douglas McIlroy bei Unix's Stammhaus von Bell Labs, während der Entwicklung von Unix, die seine Gestaltung seiner Gestaltung Toolbox -Philosophie.[1][2] Es wird durch Analogie zu einem physischen benannt Pipeline. Ein wesentliches Merkmal dieser Pipelines ist das "Versteck der Einbringungen" (Ritchie & Thompson, 1974). Dies ermöglicht wiederum mehr Klarheit und Einfachheit im System.

Dieser Artikel ist über Anonyme Rohre, wobei Daten, die von einem Prozess verfasst wurden, vom Betriebssystem bis zum nächsten Prozess gelesen werden und dieser unisch-leitende Kanal verschwindet, wenn die Prozesse abgeschlossen sind. Dies unterscheidet sich von benannte Pfeifen, wo Nachrichten an oder von einem Rohr übergeben werden, das durch eine Datei benannt wird und nach Abschluss der Prozesse bleibt. Der Standard Hülse Syntax für Anonyme Rohre soll mehrere Befehle auflisten, die durch vertikale Balken getrennt sind ("Rohre" in gemeinsamen Unix -Ausführungen):

Kommando1 | Kommando2 | Kommando3

Zum Beispiel zum Auflisten von Dateien im aktuellen Verzeichnis (ls), behalten Sie nur die Linien von ls Ausgabe mit der Zeichenfolge "Schlüssel" (Grep) und anzeigen das Ergebnis auf einer Scroll -Seite ((weniger) Ein Benutzer tippt Folgendes in die Befehlszeile eines Terminals ein:

ls -l | Grep -Schlüssel | weniger

Der Befehl ls -l wird als Prozess ausgeführt, dessen Ausgabe (STDOut) an den Eingang (stdin) des Prozesses für geleitet wird Grep -Schlüssel; und ebenfalls für den Prozess für weniger. Jeder Prozess Nimmt Eingabe aus dem vorherigen Prozess und erzeugt die Ausgabe für den nächsten Prozess über Standardströme. Jeder | teilt der Shell an, die Standardausgabe des Befehls links an die Standardeingabe des Befehls rechts mit einem zu verbinden Interprozesskommunikation Mechanismus genannt (anonyme) Pfeife, im Betriebssystem implementiert. Rohre sind unidirektional; Die Daten fließen durch die Pipeline von links nach rechts.

Beispiel

Im Folgenden finden Sie ein Beispiel für eine Pipeline, die eine Art von Art von implementiert Rechtschreibprüfung für die Netz Ressource angezeigt durch a URL. Eine Erklärung dessen, was es tut.

Locken "https://en.wikipedia.org/wiki/pipeline_(unix)" | sed 's/[^a-za-z]//g' | tr 'A-Z' 'a-z \ n' | Grep '[a-z]' ' | sortieren -u | comm -23 - <(sortieren/usr/sharing/dict/wörter) | weniger
  1. Locken erhält die Html Inhalt einer Webseite (könnte verwenden wget auf einigen Systemen).
  2. sed Ersetzt alle Zeichen (aus dem Inhalt der Webseite), die keine Leerzeichen oder Buchstaben sind. (Newlines sind erhalten.)
  3. tr Wechselt alle Großbuchstaben in Kleinbuchstaben und wandelt die Räume in den Textzeilen in Newlines um (jedes „Wort“ befindet sich jetzt in einer separaten Zeile).
  4. Grep Enthält nur Linien, die mindestens einen Kleinbuchstaben enthalten alphabetisch Zeichen (leere Zeilen entfernen).
  5. Sortieren Sortiert die Liste der Wörter in alphabetische Reihenfolge und die -U Switch entfernt Duplikate.
  6. Comm Findet Zeilen gemeinsam zwischen zwei Dateien, -23 Unterdrückt Linien, die für die zweite Datei einzigartig sind, und diejenigen, die beides gemeinsam sind, und nur diejenigen, die nur in der ersten genannten Datei gefunden werden. Das - Anstelle eines Dateinamens Ursachen Comm Verwendung der Standardeingabe (in diesem Fall aus der Rohrleitung). sortieren/usr/sharing/dict/wörter sortiert den Inhalt der Wörter alphabetische Datei als Comm erwartet, und <( ... ) gibt die Ergebnisse in eine temporäre Datei aus (über Prozesssubstitution), die Comm liest. Das Ergebnis ist eine Liste von Wörtern (Zeilen), die nicht in/usr/Share/dict/Wörtern gefunden werden.
  7. weniger Ermöglicht dem Benutzer die Ergebnisse durch die Ergebnisse.

Pipelines in Befehlszeilenschnittstellen

Alle weit verbreiteten Unix -Shells haben ein spezielles Syntaxkonstrukt für die Erstellung von Pipelines. In allen Verwendung schreibt man die Befehle nacheinander, getrennt durch die ASCII vertikale Balken Charakter | (was aus diesem Grund oft als "Pfeifencharakter" bezeichnet wird). Die Shell startet die Prozesse und ordnet die erforderlichen Verbindungen zwischen ihren Standardströmen (einschließlich einer gewissen Menge an Puffer Lagerung).

Fehlerstream

Standardmäßig die Standardfehlerströme (""Stderr") der Prozesse in einer Pipeline werden nicht durch das Rohr weitergegeben; stattdessen werden sie zusammengeführt und an die gerichtet Konsole. Viele Shells haben jedoch zusätzliche Syntax, um dieses Verhalten zu ändern. In dem CSH Shell zum Beispiel verwenden | & Anstatt von | bedeutet, dass der Standardfehlerstrom auch mit der Standardausgabe zusammengeführt und dem nächsten Prozess gespeist werden sollte. Das Verprügeln Shell kann auch den Standardfehler mit dem Zusammenführen | & Seit Version 4.0[3] oder verwenden 2> & 1und umleiten Sie es auch in eine andere Datei.

Pipemill

In den am häufigsten verwendeten einfachen Pipelines verbindet die Shell eine Reihe von Unterprozessen über Rohre und führt externe Befehle in jedem Unterprozess aus. Somit führt die Shell selbst keine direkte Verarbeitung der Daten durch, die durch die Pipeline fließen.

Es ist jedoch möglich, dass die Shell die Verarbeitung direkt mit einem sogenannten Verarbeitung durchführt Mühle oder Pipemill (seit einem while Der Befehl wird verwendet, um die Ergebnisse aus dem ersten Befehl zu "abgeben"). Dieses Konstrukt sieht im Allgemeinen aus wie:

Befehl | während lesen -r var1 var2 ...; tun  # Verarbeiten Sie jede Zeile unter Verwendung von Variablen wie in var1, var2 usw. angemessen  # (Beachten Sie, dass dies eine Unterschale sein kann: var1, var2 usw. ist nicht verfügbar  # Nach der while Loop endet endet; Einige Muscheln wie ZSH und neuer  # Versionen von Korn Shell, verarbeiten Sie die Befehle links vom Rohr  # Operator in einer Unterschale)  erledigt 

Eine solche Pipemill kann nicht wie beabsichtigt funktionieren, wenn der Körper der Schleife Befehle enthält, wie z. Katze und ssh, das lesen aus Stdin:[4] Auf der ersten Iteration der Schleife, ein solches Programm (nennen wir es der Abfluss) wird die verbleibende Ausgabe von lesen Befehlund die Schleife endet dann (mit Ergebnissen abhängig von den Besonderheiten des Abflusses). Es gibt einige mögliche Möglichkeiten, dieses Verhalten zu vermeiden. Erstens unterstützen einige Abflüsse eine Option zum Deaktivieren des Lesens von Stdin (z.B. ssh -n). Alternativ, wenn der Abfluss nicht der Fall ist brauchen Um Eingaben von zu lesen Stdin Um etwas Nützliches zu tun, kann es gegeben werden < /dev/null als Eingabe.

Da alle Komponenten eines Rohrs parallel ausgeführt werden, gilt eine Hülle typischerweise zu einem Subprozess (eine Unterschale), um ihren Inhalt zu bewältigen, was es unmöglich macht, variable Änderungen in die Außenhülle zu verbreiten. Um dieses Problem zu beheben, kann die "Pipemill" stattdessen von a gefüttert werden Hier Dokument enthält a Befehlssubstitution, was darauf wartet, dass die Pipeline das Laufen beendet, bevor er durch den Inhalt fällt. Alternativ a benannte Pfeife oder ein Prozesssubstitution kann für die parallele Ausführung verwendet werden. Gnu Bash hat auch a lastpipe Option zum Deaktivieren der Gablinge für die letzte Rohrkomponente.[5]

Pipelines programmatisch erstellen

Pipelines können unter Programmsteuerung erstellt werden. Die Unix Rohr() Systemanruf bittet das Betriebssystem, ein neues zu konstruieren Anonyme Pfeife Objekt. Dies führt im Prozess zu zwei neuen, geöffneten Dateideskriptoren: dem schreibgeschützten Ende des Rohrs und dem nur Schreibende. Die Rohrenden scheinen normal zu sein, anonym Dateideskriptoren, außer dass sie keine Fähigkeit haben zu suchen.

Vermeiden Sackgasse Und die Parallelität ausnutzen, der Unix -Prozess mit einem oder mehreren neuen Rohren wird dann allgemein anrufen Gabel() neue Prozesse erstellen. Jeder Prozess schließt dann das Ende des Rohrs, das es nicht verwendet, bevor Daten erstellt oder konsumiert werden. Alternativ kann ein Prozess neu erzeugen Themen und verwenden Sie das Rohr, um zwischen ihnen zu kommunizieren.

Benannte Pfeifen Kann auch mit Verwendung erstellt werden mkfifo () oder mknod () und dann als Eingabe- oder Ausgabedatei für Programme dargestellt, während sie aufgerufen werden. Sie ermöglichen Multi-Pfad-Rohren und sind besonders effektiv in Kombination mit Standardfehlerumleitung oder mit T -Shirt.

Implementierung

In den meisten Unix-ähnlichen Systemen werden alle Prozesse einer Pipeline gleichzeitig gestartet, wobei ihre Streams angemessen angeschlossen und von der verwaltet werden Planer zusammen mit allen anderen Prozessen, die auf der Maschine ausgeführt werden. Ein wichtiger Aspekt davon, der Unix -Pipes von anderen Rohrimplementierungen abhebt, ist das Konzept von Pufferung: Zum Beispiel kann ein Sendeprogramm 5000 produzieren Bytes pro zweiteund ein Empfangsprogramm kann möglicherweise nur 100 Bytes pro Sekunde akzeptieren, aber keine Daten gehen verloren. Stattdessen wird die Ausgabe des Sendeprogramms im Puffer gehalten. Wenn das Empfangsprogramm bereit ist, Daten zu lesen, liest das nächste Programm in der Pipeline aus dem Puffer. Wenn der Puffer gefüllt ist, wird das Sendeprogramm gestoppt (blockiert), bis zumindest einige Daten vom Puffer vom Empfänger entfernt werden. In Linux beträgt die Größe des Puffers 65.536 Bytes (64 kib). Ein Open-Source-Dritter-Filter rief an Bfr ist bei Bedarf größere Puffer zur Verfügung.

Netzwerkrohre

Werkzeuge wie netcat und SOCAT Kann Rohre mit TCP/IP verbinden Steckdosen.

Geschichte

Das Pipeline -Konzept wurde von erfunden von Douglas McIlroy[6] und zuerst in der beschrieben Mannseiten von Version 3 Unix.[7] McIlroy bemerkte so viel Zeit Befehlsschalen Die Ausgabedatei von einem Programm als Eingabe an einen anderen übergeben.

Seine Ideen wurden 1973 umgesetzt, als ("in einer fieberhaften Nacht", schrieb McIlroy) Ken Thompson fügte die hinzu Rohr() Systemanruf und Rohre zur Schale und mehrere Dienstprogramme in Version 3 Unix. "Am nächsten Tag", fuhr McIlroy fort ", sah eine unvergessliche Orgie von Einzeilern, als sich alle auf die Aufregung der Sanitäranschlüsse anschloss." McIlroy schreibt Thompson auch dem zu | Notation, die die Beschreibung der Rohrsyntax in stark vereinfachte Version 4.[8][7]

Obwohl unabhängig voneinander entwickelt, sind UNIX -Pipes mit den von Ken Lochner entwickelten „Kommunikationsdateien“ zusammen und gehen davon voraus [9] in den 1960er Jahren für die Dartmouth Time Sharing System.[10]

Im Tony Hoare Kommunizieren von sequentiellen Prozessen (CSP) McIlroys Rohre werden weiter entwickelt.[11]

Der Roboter im Symbol für Apfel's Automator, das auch ein Pipeline -Konzept verwendet, um sich wiederholte Befehle zusammenzuschließen, hält eine Pfeife in Hommage an das ursprüngliche Unix -Konzept.

Other operating systems

Diese Funktion von Unix wurde von anderen Betriebssystemen ausgeliehen, wie z. MS-DOS und die CMS -Pipelines Paket auf VM/CMS und MVSund wurde schließlich zur Bezeichnung als als bezeichnet Rohre und Filter Designmuster von Softwareentwicklung.

Siehe auch

Verweise

  1. ^ Mahoney, Michael S. "Das Unix Oral History Project: Release.0, der Anfang". McIlroy: Es war einer der wenigen Orte, an denen ich die Managementkontrolle über Unix fast ausübte, ja, ja.
  2. ^ "Archivierte Kopie". cm.bell-labs.com. Archiviert von das Original am 8. Mai 1999. Abgerufen 22. Mai 2022.{{}}: CS1 Wartung: Archiviertes Kopie als Titel (Link)
  3. ^ "Bash -Release -Notizen". tiswww.case.edu. Abgerufen 2017-06-14.
  4. ^ "Shell Loop -Interaktion mit SSH". 6. März 2012. archiviert von das Original am 6. März 2012.
  5. ^ John1024. "Wie kann ich die Befehlsergebnisse" Find "als Array in Bash speichern?". Paketüberfluss.
  6. ^ "Die Schaffung des Unix -Betriebssystems". Bell Labs. Archiviert von das Original Am 14. September 2004.
  7. ^ a b McIlroy, M. D. (1987). A Research Unix Reader: Annotierte Auszüge aus dem Programmierhandbuch, 1971–1986 (PDF) (Technischer Bericht). Cstr. Bell Labs. 139.
  8. ^ http://www.linfo.org/pipe.html Pipes: Eine kurze Einführung durch das Linux Information Project (LINFO)
  9. ^ http://www.cs.rit.edu/~swm/history/dts.doc[Bare URL DOX/DOCX -Datei]
  10. ^ "Archivierte Kopie". cm.bell-labs.com. Archiviert von das Original am 20. Februar 1999. Abgerufen 22. Mai 2022.{{}}: CS1 Wartung: Archiviertes Kopie als Titel (Link)
  11. ^ https://swtch.com/~rsc/thread/ Bell Labs und CSP -Threads (Russ Cox)

Externe Links