Trójnik nie pobiera całej mocy z rury


12

Mam skrypt wykonujący polecenia takie jak:

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

Problem jest prawdopodobnie w potoku do tee . Nie wydaje się, aby uzyskać całą moc wyjściową. Gdy aplikacja kończy pracę, brakuje kilku ostatnich wierszy danych wyjściowych (zwykle tych zawierających błąd krytyczny). Kiedy uruchamiam aplikację bez potoku tee, otrzymuję je na wyjściu.

Jak zmusić skrypt do czekania, aż tee zakończy przetwarzanie wszystkich danych wyjściowych?


Czy działa OK, jeśli umieścisz go w pliku, a nie w standardowym pliku?
Pilot6

Odpowiedzi:


23

Błąd krytyczny prawdopodobnie pojawia się w STDERR (2), a nie w STDOUT (1). Możesz przekierować STDERR do STDOUT za pomocą, 2>&1a następnie potok powinien go również przechwycić.

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

Jeśli masz problemy z buforowaniem u góry, możesz zmusić go do stanu niebuforowanego:

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

Dobrze, zbliżamy się. Teraz widzę, że błąd krytyczny jest drukowany, ale znowu nie jest kompletny. Linia z błędem kończy się na środku, a echo jest kontynuowane. Nadal występuje problem z opróżnianiem bufora lub po prostu czekaniem na ukończenie tej części.
Ladislav Mrnka

Edytowane. Dość rzadko z mojego doświadczenia, że ​​coś tak całkowicie prześlizguje się przez bufory przy wyjściu, ale warto spróbować.
Oli

1
Gotowy! Dziękuję Ci. Mogę zadawać zbyt wiele pytań, ale czy ktoś rozumie, dlaczego muszę wyłączyć buforowanie podczas przesyłania do innego procesu?
Ladislav Mrnka

@Oli Bardzo dobry!
Pilot6

6

Ponieważ komunikaty o błędach są zwykle wyświetlane w STDERR (deskryptor pliku 2), musisz przekierować zarówno STDOUT, jak i STDERR, aby tee:

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

Gdy to zrobisz ./some_app -i $INDEX | tee $LOG, przekierowujesz tylko STDOUT do tee.

|& spowoduje przekierowanie STDOUT i STDERR.

Jeśli nie możesz przekierować tylko STDOUT (tak jak byłeś):

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

Z drugiej strony, jeśli chcesz przekierować tylko STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.