Linux / Commande tee : afficher et enregistrer la sortie d’un pipeline
tee copie son entrée standard vers sa sortie standard et vers un ou plusieurs fichiers. Il permet de voir une sortie tout en la conservant, ou d'enregistrer une étape d'un pipeline avant de poursuivre le traitement. Par défaut, il remplace le contenu des fichiers indiqués ; -a ajoute les données à la fin.
La sortie standard peut être un terminal ou le tube qui alimente la commande suivante. Tee ne connaît pas l'origine des données : il enregistre seulement ce qui arrive sur son entrée standard. Les messages d'erreur du producteur restent séparés tant que le shell ne les redirige pas vers ce flux.
Syntaxe et répertoire d'exercice
commande | tee [options] fichier [autres-fichiers…]
Les exemples suivants utilisent Bash et GNU tee. Consultez man tee pour les options de votre système. Créez un répertoire neuf afin de réserver les écrasements aux données de cet exercice :
tee_lab=$(mktemp -d "$HOME/tee-lab.XXXXXX")
cd -- "$tee_lab"
printf 'zebra\napple\nbanana\n' > names.txt
Notez le chemin du répertoire pour retrouver les fichiers. Vous pourrez ensuite le quitter avec cd "$HOME". Les commandes tee qui suivent écrivent uniquement dans les fichiers nommés dans ce répertoire.
Voir et enregistrer le même contenu
printf 'status=ok\n' | tee result.txt
status=ok
La ligne s'affiche et result.txt contient exactement la même ligne. Vous pouvez contrôler le fichier avec cat result.txt. Pour conserver également une deuxième copie :
printf 'status=ok\n' | tee result-copy-a.txt result-copy-b.txt
Les deux fichiers reçoivent les données, et une seule copie passe vers la sortie standard. Si l'un des chemins désigne déjà un document à conserver, choisissez un autre nom ou sauvegardez-le avant la commande.
Ajouter avec -a plutôt que remplacer
Ajoutez une deuxième ligne au fichier de résultat :
printf 'step=2\n' | tee -a result.txt
cat result.txt
Tee affiche d'abord step=2. Le contrôle avec cat affiche ensuite les deux lignes status=ok et step=2. Sans -a, la deuxième commande aurait remplacé le contenu précédent.
Le même principe permet de noter l'heure d'une exécution :
date | tee run-time.txt
date | tee -a run-time.txt
Chaque date est affichée au moment de sa production, et le fichier finit avec deux lignes. Leur valeur et leur format dépendent de l'heure et de l'environnement local ; il n'existe donc pas de date fixe à attendre pour cet exemple.
Continuer le traitement après la sauvegarde
Pour conserver le résultat d'un tri avec sort tout en affichant son début avec head :
LC_ALL=C sort names.txt | tee names.sorted | head -n 2
cat names.sorted
Sur nos trois lignes, le premier affichage donne apple puis banana. Le fichier contient les trois lignes triées, dont zebra. Cette petite entrée ne montre cependant pas tous les effets d'une fermeture anticipée du tube.
Sur un flux plus grand, head peut quitter dès qu'il a lu les lignes demandées. Par défaut, GNU tee quitte immédiatement lorsqu'une écriture vers un tube échoue ; cela peut empêcher une copie complète vers les autres sorties. L'option GNU -p permet de continuer à alimenter les sorties restantes lorsqu'un consommateur du tube s'arrête tôt :
seq 1 100000 | tee -p sequence-complete.txt | head -n 3
wc -l < sequence-complete.txt
La première partie affiche 1, 2, 3. Le comptage attendu du fichier est 100000, tant que la production et l'écriture se terminent sans autre erreur. -p ne répare pas une erreur disque et ne transforme pas une production infinie en tâche terminée. Pour un traitement important, contrôlez aussi les statuts d'exécution.
Inclure la sortie d'erreur quand c'est voulu
Le tube | transporte la sortie standard. Pour observer la différence, produisez volontairement un message sur chaque flux :
bash -c 'printf "sortie\n"; printf "erreur\n" >&2' | tee stdout-only.txt
Les deux messages peuvent apparaître dans le terminal, mais stdout-only.txt contient seulement sortie. L'erreur contourne tee. Pour réunir les deux flux avant l'enregistrement :
bash -c 'printf "sortie\n"; printf "erreur\n" >&2' 2>&1 | tee combined.txt
Le fichier contient maintenant sortie puis erreur. Placez 2>&1 sur la commande productrice, avant le tube. Cette fusion ne conserve pas une étiquette indiquant le flux d'origine et n'offre pas de garantie générale sur l'ordre de messages émis par plusieurs processus ou soumis à des mises en tampon différentes.
Détecter une erreur du producteur
Dans Bash, le statut d'un pipeline correspond normalement à sa dernière commande. Un producteur peut donc échouer alors que tee réussit à enregistrer les données reçues. Pour le constater sans modifier votre session, utilisez un sous-shell :
(
set -o pipefail
bash -c 'printf "partiel\n"; exit 7' | tee partial.txt
printf 'Statut du pipeline : %s\n' "$?"
)
partiel
Statut du pipeline : 7
Avec pipefail, le statut est celui de la commande non réussie la plus à droite, ou 0 si toutes réussissent. Le fichier partial.txt contient bien une ligne, mais cette présence ne prouve pas que la production s'est terminée correctement. Testez le statut du pipeline immédiatement dans un script, avant de lancer l'étape qui utilisera le résultat. Les parenthèses limitent le réglage pipefail à ce sous-shell.
Le manuel Bash sur les pipelines décrit ce calcul et la connexion des flux. Pipefail modifie le statut observé ; il ne suffit pas à définir à lui seul toute la gestion des erreurs d'un script.
Comprendre les permissions et les options
Dans une commande de la forme sudo commande > fichier, le shell courant ouvre la destination de la redirection avant d'exécuter la commande privilégiée. Donner des droits à la commande productrice ne donne donc pas ces droits à cette ouverture de fichier.
Quand la tâche d'administration le justifie, la forme commande | sudo tee chemin fait ouvrir la destination par tee avec les droits nécessaires. Vérifiez le contenu et le chemin exact avant de l'utiliser : tee remplace toujours le fichier par défaut. Pour éviter l'affichage de sa copie sur le terminal, redirigez sa sortie standard vers /dev/null ; cela ne supprime ni l'écriture du fichier ni les messages d'erreur. N'exposez pas de secret dans une sortie enregistrée ou affichée inutilement.
| Option | Effet |
|---|---|
-a |
Ajouter à la fin des fichiers au lieu de les remplacer. |
-i |
Ignorer les signaux d'interruption ; ce n'est pas une option de journalisation des erreurs. |
-p |
Avec GNU tee, adapter la gestion des erreurs de tube pour continuer vers les autres sorties disponibles. |
Ne faites pas lire un fichier pour le réécrire sur lui-même par tee : l'ouverture en écriture peut en détruire le contenu avant sa lecture complète. Utilisez une destination distincte, vérifiez le résultat et gardez l'original si vous devez pouvoir revenir en arrière. Les règles exactes de remplacement, d'ajout et de traitement des sorties figurent dans le manuel officiel de GNU tee.




