Ich habe gerade ein paar Befehle in einem Terminal ausgeführt und mich gefragt, ob Unix / Linux beim Ausführen von Pipe-Befehlen Verknüpfungen verwendet.
Nehmen wir zum Beispiel an, ich habe eine Datei mit einer Million Zeilen, von denen die ersten 10 enthalten hello world
. Wenn Sie den Befehl ausführen, grep "hello world" file | head
stoppt der erste Befehl, sobald er 10 Zeilen findet, oder durchsucht er zuerst die gesamte Datei?
command-line
pipe
utilities
efficiency
Verärgerte Ziege
quelle
quelle
-m
Argument.Antworten:
Art von. Die Shell hat keine Ahnung, was die von Ihnen ausgeführten Befehle bewirken, sie verbindet lediglich den Ausgang des einen mit dem Eingang des anderen.
Wenn
grep
mehr als 10 Zeilen mit der Aufschrift "Hallo Welt" gefundenhead
werden, werden alle 10 gewünschten Zeilen angezeigt, und die Pipe wird geschlossen. Dadurch wirdgrep
SIGPIPE beendet, sodass keine sehr großen Dateien weiter gescannt werden müssen.quelle
grep
würde weiterhin Ausgaben in eine Leere senden, ähnlich wie/dev/null
Wenn ein Programm versucht, in eine Pipe zu schreiben und kein Prozess aus dieser Pipe gelesen wird, empfängt das Schreibprogramm ein SIGPIPE- Signal. Die Standardaktion beim Empfang von SIGPIPE ist das Beenden des Programms. Ein Programm kann das SIGPIPE-Signal ignorieren. In diesem Fall gibt der Schreibvorgang einen Fehler zurück (
EPIPE
).In Ihrem Beispiel sehen Sie in der folgenden Zeitleiste, was passiert:
grep
undhead
werden parallel gestartet.grep
Liest eine Eingabe und beginnt sie zu verarbeiten.grep
Produziert irgendwann einen ersten Teil der Ausgabe.head
liest den ersten Block und schreibt ihn aus.grep
möglicherweise zuerst Schluss gemacht),head
wird möglicherweise die gewünschte Anzahl von Zeilen ausgedruckt. An dieser Stelle wird beendethead
.grep
undhead
-Vorgangsgrep
haben sich möglicherweise einige Daten angesammelt und wurden noch nicht ausgedruckt. Beimhead
Beenden werdengrep
möglicherweise Eingaben gelesen oder es wird eine interne Verarbeitung durchgeführt. In diesem Fall wird die Verarbeitung fortgesetzt.grep
werden die Daten, die es verarbeitet, ausgeschrieben. An diesem Punkt erhält es ein SIEGEL und stirbt.Es ist wahrscheinlich, dass
grep
ein wenig mehr Eingaben verarbeitet werden als unbedingt erforderlich, normalerweise jedoch nur ein paar Kilobyte:head
Liest normalerweise Blöcke von einigen Kilobyte ein (da dies effizienter ist als das Ausgeben einesread
Systemaufrufs für jedes Byte - dieses Verhalten wird als Pufferung bezeichnet), sodass der Rest des letzten Blocks nach der gewünschten letzten Zeile verworfen wird.grep
Möglicherweise haben sich einige Daten angesammelt, die bereit sind, ein Ausgabeabschnitt zu werden (erneutes Puffern). Es wird SIGPIPE empfangen, wenn es versucht, seinen Ausgabepuffer zu leeren.Alles in allem ist das System präzise ausgelegt, damit sich Filterdienstprogramme auf natürliche Weise effizient verhalten. Programme, die weiterarbeiten müssen, wenn ihr Ausgangskanal ausfällt, müssen das SIGPIPE-Signal ignorieren.
quelle
Die Pipeline funktioniert folgendermaßen: Sie führt zuerst den ersten Befehl und dann in Ihrem Fall den zweiten Befehl aus.
Das heißt, lassen Sie uns
A|B
den Befehl geben. Dann ist es ungewiss, obA
oder obB
erst begonnen wird. Sie starten möglicherweise genau zur gleichen Zeit, wenn mehrere CPUs vorhanden sind. Eine Pipe kann eine undefinierte, aber begrenzte Datenmenge enthalten.Wenn B versucht, aus der Pipe zu lesen, aber keine Daten verfügbar sind,
B
wird gewartet, bis die Daten eingehen. Wenn SieB
vonB
einer Festplatte gelesen haben , besteht möglicherweise dasselbe Problem und Sie müssen warten, bis der Lesevorgang für die Festplatte abgeschlossen ist . Eine nähere Analogie wäre das Lesen von einer Tastatur. DortB
müsste man warten, bis ein Benutzer eingibt. In all diesen Fällen hat B eine "Lese" -Operation gestartet und muss warten, bis sie beendet ist. WennB
jedoch ein Befehl so ist, dass er nur eine Teilausgabe benötigt, wird dieserA
nach einem bestimmten Punkt, an dem derB
Eingangspegel erreicht istA
, von SIGPIPE beendetWenn
A
versucht wird, in die Pipe zu schreiben, und die Pipe voll ist,A
muss abgewartet werden, bis etwas Platz in der Pipe frei wird.A
könnte das gleiche Problem haben, wenn es in ein Terminal schreibt. Ein Terminal verfügt über eine Flusskontrolle und kann das Datentempo verringern. In jedem Fall hat toA
eine "Schreib" -Operation gestartet und wartet, bis die Schreiboperation beendet ist.A
undB
verhalten sich wie Co-Prozesse, obwohl nicht alle Co-Prozesse mit einer Pipe kommunizieren. Keiner hat die volle Kontrolle über den anderen.quelle
head
beenden), tritt im Programm ein SIGPIPE-Signal auf, und das Standardverhalten ist das Beenden.grep
hat keine direkte Kontrolle über die Pipe (sie empfängt nur Daten) und die Pipe hat keine direkte Kontrolle übergrep
(sie sendet nur Daten) ...Was
grep
oder ein anderes Programm tut, hängt ganz von der internen Logik dieses Programms ab. Wenn Sie sagen ,grep
über Kommandozeilenoptionen einen früher machen austritt wenn gefunden , dann wird es, sonst wird es zu sehr tuckert auf der Datei für das Muster am Ende der Suche ...Das Terminal ist ebenfalls ziemlich unabhängig von den internen Abläufen
grep
und denshell
Leitungsaktionen des Terminals. Das Terminal ist im Grunde genommen nur eine Startrampe und eine Ausgabeanzeige.quelle