Tee no obtiene toda la salida de la tubería

12

Tengo un script que ejecuta comandos como:

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

El problema está probablemente en la tubería hacia tee. No parece obtener toda la salida. Cuando la aplicación se cierra, faltan las últimas líneas de la salida (generalmente las que contienen un error fatal). Cuando ejecuto la aplicación sin canalización tee, los obtengo en la salida.

¿Cómo puedo forzar que el script espere a que T complete el procesamiento de toda la salida?

Ladislav Mrnka
fuente
¿Funciona bien si lo unes a un archivo, no stdout?
Piloto6

Respuestas:

23

El error fatal probablemente salga en STDERR (2), no en STDOUT (1). Puede redirigir STDERR a STDOUT con 2>&1y luego la tubería también debe capturarlo.

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

Si tiene problemas de almacenamiento en la parte superior, podría forzarlo a un estado sin búfer:

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG
Oli
fuente
Bien, nos estamos acercando. Ahora veo que se está imprimiendo un error fatal, pero nuevamente no está completo. La línea con el error acaba en el medio y la salida de eco continúa. Todavía hay algún problema con el búfer de lavado o simplemente esperando que se complete esa parte.
Ladislav Mrnka
Editado Bastante raro en mi experiencia que algo se deslice completamente a través de los amortiguadores a la salida, pero vale la pena intentarlo.
Oli
1
¡Hecho! Gracias. Puedo estar haciendo demasiadas preguntas, pero ¿alguien entiende por qué necesito desactivar el almacenamiento en búfer al conectar a otro proceso?
Ladislav Mrnka
@Oli ¡Muy buena!
Piloto6
6

Como los mensajes de error normalmente se muestran en STDERR (descriptor de archivo 2), debe redirigir tanto STDOUT como STDERR para tee:

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

Cuando lo hace ./some_app -i $INDEX | tee $LOG, solo está redirigiendo el STDOUT a tee.

|& hará que tanto STDOUT como STDERR sean redirigidos.

Si no puede redirigir solo el STDOUT (como era):

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

Por otro lado, si desea redirigir solo el STDERR:

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