Angenommen, ich möchte mehrere Programme parallel ausführen und ihre Ausgaben zu einer Pipe kombinieren:
sh -c '
(echo qqq; echo qqq2; echo qqq3)&
(echo www; echo www2; echo www3)&
(echo eee; echo eee2; echo eee3)&
wait; wait; wait'
Dieser Shell-Ansatz funktioniert in diesem einfachen Fall gut, aber ich erwarte, dass er fehlschlägt, wenn Programme mehr und längere Zeilen gepuffert ausgeben, wie folgt (konstruiert):
qqq
qqwww
q2
qqq3www2
wwweee3
eee2
eee3
Eine der Lösungen, die ich verwenden sollte, war tail -f
:
tail -n +0 -q -f <(echo qqq; echo qqq2; echo qqq3) <(echo www; echo www2; echo www3) <(echo eee; echo eee2; echo eee3)
Dies ist jedoch eine nicht optimale Option: Sie gibt Daten nur schleppend aus und wird nicht beendet. Ich sehe die Ausgaben nicht in der Reihenfolge "Schlaf", sondern in der Reihenfolge der Argumente in diesem Fall:
tail -n +0 -q -f <(sleep 1; echo qqq; sleep 1; echo qqq2; echo qqq3) <(echo www; echo www2; sleep 10; echo www3) <(echo eee; sleep 4; echo eee2; echo eee3) | cat
Ich habe ein spezielles kleines Programm dafür implementiert , glaube aber, dass es einen Standard-guten Weg geben sollte, dies zu tun.
Wie geht das mit Standardwerkzeugen (und ohne tail -f
Nachteil)?
syslog
...syslog
nicht für Protokolle, sondern für etwas Benutzerdefiniertes als OK angesehen?-s
Option für den Schwanz zu erwähnen . zBtail -f -s .1 file
reduziert die Schleifenverzögerung von 1 Sekunde auf 0,1 Sekunden.Antworten:
GNU Parallel.
Aus den Versionshinweisen vom August 2013:
Beispielsweise:
parallel --line-buffer <jobs
Wo
jobs
enthält:short.sh
::long.sh
::Ausgabe:
quelle
Eine Lösung, die Sperren implementiert:
Es sollte einen schnelleren Weg geben, eine Sperre zu erstellen, als das Dateisystem zu verwenden.
quelle
Ich kann mir nichts Einfaches vorstellen, das Ihnen helfen könnte, wenn Ihre Zeilen so lang sind, dass ein Programm in den Ruhezustand versetzt wird, bevor es in der Lage war, eine Zeile an stdout zu schreiben.
Wenn Ihre Zeilen jedoch kurz genug sind, um vor dem Prozesswechsel vollständig geschrieben zu werden, und Ihr Problem darin besteht, dass das Generieren einer Zeile sehr lange dauert, können Sie die Ausgabe mit read puffern.
Z.B:
quelle
Sie können eine Named Pipe mit
mkfifo
erstellen, die gesamte Ausgabe in die Named Pipe sichern und für Ihre gesammelten Daten separat von der Named Pipe lesen:quelle
job1
undjob2
Ausgang lang (> 4096 Bytes) Linien? Dies scheint als Pipe-Äquivalent des ersten Code-Beispiels in der Frage bezeichnet zu werden.tee
, was genau so klingt, wie Sie es möchten. Schauen Sie sich möglicherweise die Internasyslog
oder andere Protokollierungswerkzeuge an, da diese die Ausgabe von mehreren Stellen definitiv in einer Protokolldatei zusammenfassen. Das Sperren kann durchaus die richtige Antwort sein, wie auch von @emmanual vorgeschlagen.