Ich möchte häufig relativ kurze Zeichenfolgendaten (kann aber auch mehrere Zeilen umfassen) an Befehlszeilenprogramme übergeben, die wiederholt nur Eingaben aus Dateien (z. B. wdiff) akzeptieren. Sicher kann ich eine oder mehrere temporäre Dateien erstellen, die Zeichenfolge dort speichern und den Befehl mit dem Dateinamen als Parameter ausführen. Es sieht für mich jedoch so aus, als wäre dieses Verfahren äußerst ineffizient, wenn Daten tatsächlich auf die Festplatte geschrieben würden, und es könnte die Festplatte mehr als schädigen, wenn ich dieses Verfahren viele Male wiederhole, z. B. wenn ich einzelne Zeilen langen Textes einspeisen möchte Dateien zu wdiff. Gibt es eine empfohlene Möglichkeit, dies zu umgehen, indem beispielsweise Pseudodateien wie Pipes zum temporären Speichern der Daten verwendet werden, ohne sie tatsächlich auf die Festplatte zu schreiben (oder nur, wenn sie eine kritische Länge überschreiten). Beachten Sie, dass wdiff zwei Argumente akzeptiert undwdiff <"text"
.
98
xargs
?xargs
würden die Eingabezeilen aus den Datei-String-Argumenten für den Befehl bestehen. Aber ich brauche das Gegenteil.echo $data_are_here | dumb_program
?Antworten:
Verwenden Sie eine Named Pipe . Zur Veranschaulichung:
Das
-e
Tells-Echo interpretiert das Newline-Escape (\n
) richtig . Dies blockiert, dh Ihre Shell bleibt hängen, bis etwas die Daten aus der Pipe liest.Öffnen Sie eine andere Shell irgendwo und im selben Verzeichnis:
Sie werden das Echo lesen, das die andere Shell freigibt. Obwohl die Pipe als Dateiknoten auf der Festplatte vorhanden ist, werden die Daten, die sie passieren, nicht übertragen. alles spielt sich im Gedächtnis ab. Sie können
&
das Echo im Hintergrund ( ) anzeigen.Die Pipe verfügt über einen 64-KB-Puffer (unter Linux) und blockiert wie ein Socket den Writer, wenn er voll ist, sodass Sie keine Daten verlieren, solange Sie den Writer nicht vorzeitig beenden.
quelle
/tmp
wird in den meisten Distributionen so konfiguriert, dass eintmpfs
Dateisystem im RAM verwendet wird. Wenn Sie eine Datei/tmp
darin schreiben, wird sie direkt in Ihren Arbeitsspeicher geschrieben. Dies ist eine gute Antwort für semi-ausfallsichere Dateien, auf die schnell zugegriffen und viele Male neu geschrieben werden muss.In Bash können Sie die
command1 <( command0 )
Umleitungssyntax verwenden, die diecommand0
stdout umleitet und an eine übergibtcommand1
, die einen Dateinamen als Befehlszeilenargument verwendet. Dies wird als Prozesssubstitution bezeichnet .Einige Programme, die Dateinamen-Befehlszeilenargumente verwenden, benötigen eine echte Direktzugriffsdatei, daher funktioniert diese Technik bei diesen Programmen nicht. Es funktioniert jedoch gut mit
wdiff
:Im Hintergrund wird ein FIFO erstellt, der Befehl innerhalb
<( )
des FIFO weitergeleitet und der Dateideskriptor des FIFO als Argument übergeben. Um zu sehen, was los ist, versuchen Sie es mitecho
, um das Argument zu drucken, ohne etwas damit zu tun:Das Erstellen einer Named Pipe ist flexibler (wenn Sie eine komplizierte Umleitungslogik mit mehreren Prozessen schreiben möchten), aber für viele Zwecke ist dies ausreichend und offensichtlich einfacher zu handhaben.
Es gibt auch die
>( )
Syntax, wann Sie sie als Ausgabe verwenden möchten, zSiehe auch das Spickzettel für Bash-Umleitungen für verwandte Techniken.
quelle
ssh -F <(vagrant ssh-config) default
echt nett aber leider.wdiff ist ein Sonderfall, da 2 Dateinamenargumente erforderlich sind. Für alle Befehle, die nur 1 Argument benötigen und die hartnäckig ablehnen, etwas anderes als ein Dateinamenargument zu verwenden, gibt es 2 Optionen:
Der Dateiname '-' (dh ein Minuszeichen) funktioniert ungefähr die Hälfte der Zeit. Es scheint davon abzuhängen, um welchen Befehl es sich handelt und ob der Entwickler des Befehls diesen Fall abfängt und wie erwartet behandelt. z.B
Es gibt eine psuedo-Datei mit dem Namen / dev / stdin, die unter Linux existiert und verwendet werden kann, wenn ein Befehl unbedingt einen Dateinamen erfordert. Dies funktioniert mit größerer Wahrscheinlichkeit, da für den Befehl keine spezielle Behandlung von Dateinamen erforderlich ist. Wenn ein FIFO funktioniert oder die Bash- Prozess-Substitutionsmethode funktioniert, sollte dies auch funktionieren und ist nicht Shell-spezifisch. z.B
quelle