Bisher kenne ich den Piping-Mechanismus als Möglichkeit, eine Reihe von Befehlen zu verbinden, indem man den stdout eines Befehls mit dem stdin des nächsten Befehls verbindet, bis der letzte Befehl erreicht ist, der seinen stdout mit der Anzeige oder einer Datei verbindet.
Wäre es jedoch möglich, eine Schleife aus Befehlen zu erstellen, sodass die Standardausgabe des letzten Befehls mit der Standardeingabe des ersten Befehls verbunden wird und vielleicht durch die Verwendung von „tee“ irgendwie die sich ändernden Werte einer bestimmten Ausgabe angezeigt werden könnten?
Antwort1
Ich bin mir nicht sicher, ob es alle Shells gibt, aber in Bash ist es möglich, allerdings nicht mit unbenannten Pipes. Also nicht mit dem |
Symbol. Aber wenn Sie eine benannte Pipe erstellen:
mkfifo fifo
Dann können Sie es verwenden:
<fifo cat | cat >fifo &
Jetzt arbeitet die Pipeline im Hintergrund, tut aber nichts. Wenn Sie die Pipe jedoch von außerhalb der Pipeline füttern:
echo x >fifo
Die Pipeline wird frei und funktioniert für immer weiter. Oder bis Sie das Rohr entleeren:
cat fifo
Die Ausgabe erfolgt einmal:
x
Um das Ganze ein wenig komplexer zu gestalten, könnte die Pipeline folgendermaßen aussehen:
<fifo cat | xargs -I@ echo @x >fifo &
Daher wird x
bei jeder Iteration ein zur Ausgabe hinzugefügt. Natürlich wird dies der Fall sein, aber nur, wenn die Iterationen beginnen, d. h. sobald die Pipe freigegeben wird, also sobald etwas zu lesen ist. Wie zuvor kann dies manuell gestartet werden:
echo x >fifo
Und jetzt schauen Sie sich an, was angezeigt wird. Sowohl als auch top
sollte eine Menge Aktivität zu sehen sein .cat
xargs
Und wie zuvor gilt: Wenn Sie die Rohrleitung entleeren, sollten Sie viele x
„s“ im Terminal sehen und die Rohrleitung wird blockiert.
Es wäre eine berechtigte Frage, warum die Pipeline geleert wird. Warum wird der cat
Befehl im Terminal ausgeführt und nichts bleibt im Kreislauf zurück? Das weiß ich nicht.
Antwort2
Sie könnten natürlich auch einfach eine Schleife erstellen und Variablen verwenden:
while true; do
a=$(echo "$a" | grep "Hey" | cut -d" " -f2 | tee -a log)
done
Dadurch wird die letzte Ausgabe gespeichert, die am Anfang wieder verwendet wird.
Antwort3
Wie die vorhandene Antwort zeigt, ist eine geloopte Pipeline in der Unix-Shell nicht möglich, ohne eine benannte Pipe zu verwenden (erstellt mitmkfifo(1)). Aber Sie können es in C machen; hier ist zum Beispiel meinschmutzig-einfache Implementierung, das nicht einmal auf das Beenden von Prozessen wartete.
Ich hoffe, Sie finden diese Informationen nützlich.