Ist es möglich, mit einer Pipe oder etwas anderem eine Befehlsschleife zu erstellen?

Ist es möglich, mit einer Pipe oder etwas anderem eine Befehlsschleife zu erstellen?

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 xbei 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 topsollte eine Menge Aktivität zu sehen sein .catxargs

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 catBefehl 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.

verwandte Informationen