Lösung 1:
Persönlich mein Favorit (erfordert Bash und andere Dinge, die bei den meisten Linux-Distributionen Standard sind)
Die Details können stark davon abhängen, was die beiden Dinge ausgeben und wie Sie sie zusammenführen möchten ...
Inhalt von command1 und command2 nacheinander in der Ausgabe:
cat <(command1) <(command2) > outputfile
Oder wenn beide Befehle alternative Versionen derselben Daten ausgeben, die Sie nebeneinander sehen möchten (ich habe dies mit snmpwalk verwendet; Zahlen auf der einen Seite und MIB-Namen auf der anderen):
paste <(command1) <(command2) > outputfile
Oder wenn Sie die Ausgabe von zwei ähnlichen Befehlen vergleichen möchten (z. B. eine Suche in zwei verschiedenen Verzeichnissen)
diff <(command1) <(command2) > outputfile
Oder wenn es sich um geordnete Ausgaben handelt, führen Sie sie zusammen:
sort -m <(command1) <(command2) > outputfile
Oder führen Sie beide Befehle gleichzeitig aus (könnte jedoch etwas durcheinander kommen):
cat <(command1 & command2) > outputfile
Der Operator <() richtet für jeden Befehl eine benannte Pipe (oder /dev/fd) ein, leitet die Ausgabe dieses Befehls in die benannte Pipe (oder /dev/fd-Dateihandle-Referenz) und übergibt den Namen an die Befehlszeile. Es gibt ein Äquivalent mit>(). Sie könnten Folgendes tun:command0 | tee >(command1) >(command2) >(command3) | command4
um beispielsweise die Ausgabe eines Befehls gleichzeitig an 4 andere Befehle zu senden.
Lösung 2:
Mit cat
können Sie zwei Streams aneinander anhängen , wie der Gorilla zeigt.
Sie können auch ein FIFO erstellen, die Ausgabe der Befehle dorthin leiten und dann mit einem beliebigen anderen Programm aus dem FIFO lesen:
mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo
Besonders nützlich für Programme, die nur eine Datei schreiben oder lesen, oder Programme mischen, die nur stdout/Datei ausgeben, mit einem, das nur das andere unterstützt.
Lösung 3:
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output
/tmp/p1
und /tmp/p2
sind Ihre Eingaberohre, während /tmp/output
ist die Ausgabe.
Lösung 4:
Ich habe dafür ein spezielles Programm erstellt:fdlinecombine
Es liest mehrere Pipes (normalerweise Programmausgaben) und schreibt sie zeilenweise nach stdout (Sie können auch das Trennzeichen überschreiben)
Lösung 5:
Seien Sie hier vorsichtig; Wenn Sie sie einfach kategorisieren, werden die Ergebnisse auf eine Weise gemischt, die Sie möglicherweise nicht möchten:Wenn es sich beispielsweise um Protokolldateien handelt, möchten Sie wahrscheinlich nicht wirklich, dass eine Zeile von einer Zeile auf halbem Weg durch eine Zeile von der anderen eingefügt wird. Wenn das in Ordnung ist, dann
tail -f /tmp/p1 /tmp/p2>/tmp/output
wird funktionieren. Wenn das nicht ist Okay, dann müssen Sie etwas finden, das Zeilenpufferung durchführt und nur vollständige Zeilen ausgibt. Syslog tut dies, aber ich bin mir nicht sicher, was es sonst noch könnte.
EDIT:Optimierung für ungepuffertes Lesen und Named Pipes:
Betrachtet man /tmp/p1 , /tmp/p2 , /tmp/p3 als Named Pipes, erstellt von "mkfifo /tmp/pN "
tail -q -f /tmp/p1 /tmp/p2 | awk '{print $0> "/tmp/p3"; close("/tmp/p3"); fflush();}' &
Auf diese Weise können wir jetzt die Ausgabe mit dem Namen "/tmp/p3" ungepuffert lesen von :
tail -f /tmp/p3
Es gibt einen kleinen Fehler, Sie müssen die 1. Eingabepipe /tmp/p1 "initialisieren" durch:
echo -n> /tmp/p1
um zu befolgen akzeptiert zuerst die Eingabe von 2nd Pipe /tmp/p2 und wartet nicht, bis etwas zu /tmp/p1 kommt. Dies kann nicht der Fall sein, wenn Sie sicher sind, dass /tmp/p1 zuerst Eingaben erhält.
Auch die Option -q wird für Tail benötigt gibt keinen Müll über Dateinamen aus.