So leiten Sie stdout von rechts nach links um

8

Das funktioniert perfekt:

./foo | ./bar

Aber ich möchte so etwas:

./bar <| ./foo

So kann ich umgekehrt herumleiten und die Argumente von foo in der Befehlszeile schneller ändern.

Die Pipe muss in Echtzeit sein - mein fooProgramm kehrt nie zurück.

Ist das möglich ?

Bilow
quelle
Nicht wirklich eine Pfeife, aber Sie könnten verwenden./bar <(./foo)
Lambert
2
oder ./bar < <(./foo)wenn barist ein Skript.
Lambert
5
Wie wäre das schneller? Suchen Sie nur nach Shell-Verknüpfungen wie Strg + A, um zum Anfang zu gelangen, und Alt + F, um jeweils ein Wort vorwärts zu gehen?
Terdon
Shell-Verknüpfungen können jedoch nützlich sein. Ich muss diese Taste immer noch mehrmals drücken, um den Cursor auf das gewünschte Argument zu bringen, während ich mit dem Cursor direkt am Ende Sekunden gewinne
Bilow
Die Eingabe von Strg + A dauert Sekunden.
Chepner

Antworten:

2
./bar < <( ./foo )

Zum Beispiel: cat < <(echo "hello there!")

Um zu verstehen, wie es funktioniert, betrachten Sie Teile des Skripts separat.

Diese Syntax: cat < /path/to/fileliest die Datei /path/to/fileund leitet sie als Standard an weiter cat.

Diese Syntax: <(echo "hello there!")bedeutet, den Befehl auszuführen und das stdout an einen Dateideskriptor wie anzuhängen /dev/fd/65. Das Ergebnis des gesamten Ausdrucks ist ein Text wie /dev/fd/65und ein Befehl, der parallel ausgeführt wird und diesen Dateideskriptor speist.

Zusammen führt das Skript nun den rechten Befehl aus, leitet ihn an einen Dateideskriptor weiter, konvertiert diesen Dateideskriptor für den linken Befehl in stdin und führt den linken Befehl aus.

Es gibt keinen Overhead, von dem ich wissen würde, es ist genau das gleiche wie a | bnur syntaktischer Zucker.

VasyaNovikov
quelle
9

Ein einfacher und richtiger Weg kann darin bestehen, eine Foobar-Funktion zu definieren.

foobar () { ./foo "$@" | ./bar ; }

(entweder in der Befehlszeile nach Bedarf oder in einigen Startskripten, wie z. B. ".bashrc"). Wann immer Sie dies tun:

foobar "this"  that   "and this also"

Das wird reichen

./foo  this   that   "and this also" | ./bar
Olivier Dulac
quelle
1
Ja, ich mache das die ganze Zeit, um das Aufwärtspfeilen und Bearbeiten des Teils des Befehls, den ich ändern möchte, zu vereinfachen, ohne den Strg-Links-Pfeil bis dahin drücken zu müssen. Sie können die Funktionsdefinition sogar als Teil des Befehls belassen : foobar() { printf '%s\n' -x "$1" -y "$2" blah blah "${@:3}" | grep -v 123; }; foobar a b abc 'cd ef'. So können Sie die Funktionsdefinition leicht anpassen, wenn Sie an etwas anderes denken. ( "${@:3}"Erweitert sich auf die Positionsparameter beginnend mit 3 und überspringt die beiden bereits verwendeten.)
Peter Cordes
Sie können nützliche Dinge wie local IFS=in einer Funktion tun und einige Variablen basierend auf den Funktionsargumenten berechnen.
Peter Cordes
4

Ich denke, Sie könnten so etwas mit einer Named Pipe machen:

mypipe=$(mktemp -d /tmp/XXXXXX)/pipe
mkfifo $mypipe
grep something < $mypipe & tail > $mypipe -f  some_input_file 
rm $mypipe

oder fügen Sie den unveränderlichen Teil des Befehls in ein Shell-Skript ein:

./foo "$@" | ./bar

und geben Sie die Argumente in fooder Skriptbefehlszeile an:

./myscript <args to foo>
ilkkachu
quelle