Das T-Stück erhält nicht die gesamte Leistung aus dem Rohr

10

Ich habe ein Skript, das Befehle ausführt wie:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

Das Problem liegt wohl in der Leitung zu tee. Es scheint nicht die gesamte Ausgabe zu erhalten. Wenn die Anwendung beendet wird, fehlen die letzten Zeilen der Ausgabe (normalerweise diejenigen, die einen schwerwiegenden Fehler enthalten). Wenn ich die App ohne Pipe starte, teebekomme ich sie in die Ausgabe.

Wie kann ich das Skript zwingen, auf den Abschlag zu warten, um die Verarbeitung aller Ausgaben abzuschließen?

Ladislav Mrnka
quelle
Funktioniert es in Ordnung, wenn Sie es in eine Datei tippen, nicht in stdout?
Pilot6

Antworten:

21

Der schwerwiegende Fehler tritt wahrscheinlich in STDERR (2) und nicht in STDOUT (1) auf. Sie können STDERR mit in STDOUT umleiten, 2>&1und dann sollte das Rohr es auch erfassen.

./some_app -i $INDEX 2>&1 | tee $LOG

Wenn Sie oben Probleme mit der Pufferung haben, können Sie diese in einen ungepufferten Zustand versetzen:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG
Oli
quelle
Gut, wir kommen näher. Jetzt sehe ich, dass ein schwerwiegender Fehler gedruckt wird, der jedoch nicht vollständig ist. Die Zeile mit dem Fehler endet gerade in der Mitte und die Echoausgabe wird fortgesetzt. Es gibt immer noch ein Problem mit dem Leeren des Puffers oder dem Warten auf den Abschluss dieses Teils.
Ladislav Mrnka
Bearbeitet. Nach meiner Erfahrung ziemlich selten, dass etwas beim Verlassen so vollständig durch die Puffer rutscht, aber es ist einen Versuch wert.
Oli
1
Erledigt! Vielen Dank. Ich stelle möglicherweise zu viele Fragen, aber versteht jemand, warum ich die Pufferung deaktivieren muss, wenn ich zu einem anderen Prozess weiterleite?
Ladislav Mrnka
@Oli Ein sehr guter!
Pilot6
6

Da die Fehlermeldungen normalerweise in STDERR (Dateideskriptor 2) angezeigt werden, müssen Sie sowohl STDOUT als auch STDERR umleiten zu tee:

./some_app -i "$INDEX" |& tee "$LOG"

Wenn Sie dies tun ./some_app -i $INDEX | tee $LOG, leiten Sie den STDOUT nur an weiter tee.

|& bewirkt, dass sowohl STDOUT als auch STDERR umgeleitet werden.

Wenn Sie nicht nur das STDOUT umleiten können (wie Sie waren):

./some_app -i "$INDEX" | tee "$LOG"

Wenn Sie jedoch nur den STDERR umleiten möchten:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
heemayl
quelle