Tee non ottiene l'intero output dalla pipe


12

Ho uno script che esegue comandi come:

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

Il problema è probabilmente nel tubo di tee. Non sembra ottenere l'intero output. Quando l'applicazione si chiude ultime poche righe dell'output (in genere quelle che contengono un errore irreversibile) mancano. Quando eseguo l'app senza pipe per teeottenerli nell'output.

Come posso forzare lo script ad aspettare che tee completi l'elaborazione di tutto l'output?


Funziona bene se lo si collega a un file, non a stdout?
Pilota 6

Risposte:


23

L'errore fatale sta probabilmente emergendo in STDERR (2), non in STDOUT (1). Puoi reindirizzare STDERR in STDOUT con 2>&1e quindi anche la pipe dovrebbe catturarlo.

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

Se hai problemi di buffering in cima, potresti forzarlo in uno stato senza buffer:

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

Bene, ci stiamo avvicinando. Ora vedo che si sta stampando un errore fatale, ma di nuovo non è completo. La riga con l'errore termina nel mezzo e l'eco continua. C'è ancora qualche problema con il buffer di flushing o semplicemente in attesa del completamento di quella parte.
Ladislav Mrnka,

Modificato. Abbastanza raro nella mia esperienza che qualcosa di così completamente sfugge ai buffer all'uscita ma vale la pena provare.
Oli

1
Fatto! Grazie. Potrei fare troppe domande ma qualcuno capisce perché devo disattivare il buffering quando eseguo il piping su un altro processo?
Ladislav Mrnka,

@Oli Molto bene!
Pilota 6,

6

Poiché i messaggi di errore vengono normalmente visualizzati su STDERR (descrittore di file 2), è necessario reindirizzare sia STDOUT che STDERR a tee:

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

Quando lo fai ./some_app -i $INDEX | tee $LOG, reindirizza solo STDOUT a tee.

|& provocherà il reindirizzamento di STDOUT e STDERR.

Se non riesci a reindirizzare solo lo STDOUT (come eri):

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

D'altra parte, se si desidera reindirizzare solo STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.