Le té n'obtient pas la sortie entière du tuyau


12

J'ai un script exécutant des commandes comme:

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

Le problème est probablement dans le tuyau tee. Il ne semble pas obtenir la sortie entière. Lorsque l'application se ferme, les dernières lignes de la sortie (généralement celles contenant une erreur fatale) sont manquantes. Lorsque j'exécute l'application sans pipe pour les teeobtenir dans la sortie.

Comment puis-je forcer le script à attendre que le tee termine le traitement de toutes les sorties?


Cela fonctionne-t-il bien si vous le connectez à un fichier, pas à stdout?
Pilot6

Réponses:


23

L'erreur fatale sort probablement dans STDERR (2), pas STDOUT (1). Vous pouvez rediriger STDERR vers STDOUT avec 2>&1et le tube devrait également le capturer.

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

Si vous avez des problèmes de mise en mémoire tampon, vous pouvez le forcer à un état sans tampon:

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

Bon, on se rapproche. Maintenant, je vois que l'erreur fatale est en cours d'impression, mais encore une fois, elle n'est pas terminée. La ligne avec l'erreur se termine juste au milieu et la sortie d'écho continue. Il y a encore un problème avec le vidage du tampon ou simplement en attente de la fin de cette partie.
Ladislav Mrnka

Édité. Assez rare dans mon expérience que quelque chose glisse si complètement à travers les tampons à la sortie, mais ça vaut le coup.
Oli

1
Terminé! Je vous remercie. Je pose peut-être trop de questions, mais quelqu'un comprend-il pourquoi je dois désactiver la mise en mémoire tampon lorsque je passe à un autre processus?
Ladislav Mrnka

@Oli Un très bon!
Pilot6

6

Comme les messages d'erreur sont normalement affichés sur STDERR (descripteur de fichier 2), vous devez rediriger STDOUT et STDERR vers tee:

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

Lorsque vous le faites, ./some_app -i $INDEX | tee $LOGvous redirigez uniquement le STDOUT vers tee.

|& entraînera la redirection de STDOUT et de STDERR.

Si vous ne pouvez pas rediriger uniquement le STDOUT (comme vous l'étiez):

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

En revanche si vous souhaitez rediriger uniquement le STDERR:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.