Quel est le but de 'tee'?

90

Tous les usages de ce que teej'ai jamais vu étaient tels:

 do_something | tee -a logfile

Ou:

do_something_else | tee logfile

Est-ce teeinventé pour ceux qui ne savent pas que vous pouvez faire la même chose avec les redirections de pipes? Tel que:

do_something >> logfile

Ou:

do_something_else > logfile

C'est pratiquement la même chose et il faut moins de frappes au clavier pour taper. Quelles sont les fonctionnalités cachées que je ne vois pas tee?

R Moog
la source
62
Comment n’a-t-on pas répondu à la toute première ligne de la page de manuel "... et écrire dans la sortie standard et les fichiers" ? Les réponses sont intéressantes, mais parler de la façon dont les tuyaux sont utiles ne fait que renforcer le fait que ce Q semble trop large et aurait peut-être dû être fermé.
Xen2050
3
@ Xen2050 On ne peut pas reprocher à une question une réponse trop large. La question est très spécifique, de même que la réponse la mieux notée actuellement .
Jon Bentley
1
@JonBentley, la question ne sonne pas comme "un problème spécifique avec suffisamment de détails pour identifier une réponse adéquate" (comme indiqué dans le dialogue de fermeture). Cela ressemble à ceci: "si votre question peut répondre à un livre entier ou si elle contient de nombreuses réponses valables (mais aucun moyen de déterminer celles qui sont correctes, le cas échéant), elle est probablement trop large pour notre format." (Source: Centre d'aide )
Xen2050
4
@ Xen2050 Lisons-nous la même question? Cela me semble très spécifique - quelle est la différence entre le tee et les pipes? Il a été répondu de manière adéquate en utilisant deux phrases. Loin d'un livre entier. Le fait que certaines réponses choisissent de prendre une tangente n'a rien à voir avec la portée de la question.
Jon Bentley
@ JonBentley: Lisons-nous la même question? R Moog de type de tri de implique une question assez bien ciblée - quelle est la différence entre tee et la redirection d' E / S ?   Le fait qu'il soit indiqué « redirection de canal de passe tel que et » n'est pas un argument en sa faveur, et constitue un argument en faveur de la fermeture, qui n'est pas clair. Mais il pose en fait plusieurs questions: «Quel est le but de ?", "Est inventé pour ceux qui ne savent pas que vous pouvez faire la même chose avec les redirections de tubes de passe ?" Au moins deux de ces questions sont trop larges. >>>teeteetee
G-Man

Réponses:

242

Ce que vous ne voyez pas que do_something | tee -a logfilemet la sortie dans logfile et à la sortie standard, tout le do_something >> logfilemet seulement dans le fichier journal.

Le but de teeest de produire un scénario à une entrée, plusieurs sorties - comme dans un croisement en "T".

MODIFIER

Il y a eu des commentaires sur la façon dont teepermet une utilisation plus facile sudo. Ceci est à côté du point: cat, ddou peut - être mieux bufferfournir cette possibilité avec de meilleures performances, si vous n'avez pas besoin les multiples sorties. Utilisez teepour ce qu'il est conçu, pas pour ce qu'il "peut aussi faire"

Eugen Rieck
la source
37
La sortie multiple est la clé. teepeut même prendre plusieurs arguments et écrire dans plusieurs fichiers à la fois.
Kamil Maciorowski
20
J'appellerais cela un raccord de tuyau de départ , pas un croisement (comme dans une intersection de route?) Le matériel entre dans un sens et sort des deux côtés.
user253751
7
Comment pourrais-je utiliser catde manière simple au lieu de teepar exemple echo /var/work/core.%p | sudo tee /proc/sys/kernel/core_pattern? echo /var/work/core.%p | sudo cat > /proc/sys/kernel/core_patternne fonctionne pas, car la redirection est traitée par le shell non-sudo. En ce qui concerne dd, echo /var/work/core.%p | sudo dd of=/proc/sys/kernel/core_patternfonctionne, mais ddest souvent un outil surpuissant capable de faire de grands dommages, en particulier sous sudo. Quant à buffer, ce n’est installé par défaut dans aucune des distributions basées sur RedHat ou Ubuntu que j’ai sous la main (ou MacOS) ...
Digital Trauma
3
@EugenRieck Je comprends ce que vous pensez de la relation 1: n entre in: out étant la fonction principale. Cependant, ni le construit, catni /bin/cattravailler pour moi dans cette situation. Peu importe d’où que ce catsoit: la >coque sera toujours traitée par le shell de niveau supérieur (non sudo). L'avantage de teeover catdans cette situation est qu'elle permet au fichier de sortie d'être transmis en tant que paramètre en ligne de commande (et non en tant que redirection). ddest certainement une option viable, mais je serais toujours en faveur teede cela
Digital Trauma
3
@EugenRieck Quel shell a catet teecomme éléments intégrés? Et quelle version de sudocan run shell builtins peut être exécutée?
Wjandrea
118

Tee n'est pas inutile

Peut-être que tu le savais quand même? Si non, lisez la suite! Ou si vous savez comment ça marche, mais vous ne savez pas pourquoi, il faut aller à la fin pour voir comment cela s’inscrit dans la philosophie Unix.

Quel est le but de tee?

Dans sa forme la plus simple, il prend des données sur une entrée standard et les écrit sur une sortie standard et sur un (ou plusieurs) fichier (s). Il a été comparé à un té de plomberie en divisant une entrée en deux sorties (et deux directions).

Exemples

Prenons votre premier exemple:

do_something | tee -a logfile

Cela prend la sortie de do_somethinget l'ajoute au fichier journal, tout en l'affichant à l'utilisateur. En fait, la page Wikipediatee présente le deuxième exemple:

Pour afficher et ajouter le résultat d'une commande à un fichier existant:

  lint program.c | tee -a program.lint

Ceci affiche la sortie standard de la commande lint program.c sur l'ordinateur et ajoute en même temps une copie de celle-ci à la fin du fichier program.lint. Si le fichier program.lint n'existe pas, il est créé.

L'exemple suivant a une autre utilisation: escalade des autorisations :

Pour autoriser l'escalade des autorisations:

cat ~/.ssh/id_rsa.pub | ssh admin@server "sudo tee -a /root/.ssh/authorized_keys2 > /dev/null"

Cet exemple montre que tee est utilisé pour contourner une limitation inhérente à la sudocommande. sudoest incapable de diriger la sortie standard vers un fichier. En vidant son flux de sortie standard dans /dev/null, nous supprimons également la sortie en miroir dans la console. La commande ci-dessus donne à l'utilisateur actuel un accès root sur un serveur via ssh, en installant la clé publique de l'utilisateur dans la liste des autorisations de clés du serveur.

Ou peut-être souhaitez-vous prendre le résultat d'une commande, l'écrire quelque part et l'utiliser également comme entrée d'une autre commande?

Vous pouvez également utiliser la commande tee pour stocker la sortie d'une commande dans un fichier et rediriger la même sortie comme entrée vers une autre commande.

La commande suivante effectuera une sauvegarde des entrées de la crontab et transmettra les entrées de la crontab en tant qu'entrée à la commande sed qui effectuera la substitution. Après la substitution, il sera ajouté en tant que nouveau travail cron.

$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab –

(crédit aux exemples d’utilisation de la commande Tee )

Tee travaille avec la philosophie Unix:

Ecrivez des programmes qui font une chose et le font bien. Écrire des programmes pour travailler ensemble. Ecrivez des programmes pour gérer les flux de texte, car c'est une interface universelle.

(Crédit aux principes de base de la philosophie Unix )

tee s'adapte à tous ceux-ci:

  • il fait une chose: crée une copie supplémentaire de l'entrée
  • cela fonctionne avec d'autres programmes parce que c'est la colle (ou une pièce de plomberie en «T» si vous préférez) qui permet à d'autres programmes de fonctionner ensemble comme dans les exemples ci-dessus
  • il le fait en manipulant un flux de texte donné sur une entrée standard
Bertieb
la source
3
@ Joe: sudo tee -aest probablement une innovation plus récente (je l'avais d'abord vu dans les guides / wikis Ubuntu, en particulier pour configurer des éléments /proc/sys, car le passage à Ubuntu était lorsque je suis passé sur un sudosystème de base (comment Ubuntu est configuré par défaut) au lieu d'utiliser suun mot de passe root). Je pense teeavant sudo, donc ce n'est pas une raison pour teeexister. Vous n’avez pas besoin teede ça, c’est simplement plus court que de taper de manière interactive sudo sh -c 'cat > output'.
Peter Cordes
1
Avec les réservoirs modernes tels que bash, vous pouvez teealimenter deux pipelines, par exemple foo | tee >(pipe2) | pipe1. Ou encore, amusez-vous ffmpeg ... |& tee /dev/tty | sed 's/.*\r// > encode.logà voir les mises à jour des lignes de statut de manière interactive sur le terminal, tout en supprimant les "lignes" qui se terminent par chariot-return au lieu de newline pour la journalisation réelle. (ie filtrer les mises à jour de la ligne d'état). En général, vous pouvez coller un tee /dev/ttyemplacement quelconque dans un pipeline en tant qu'impression de débogage.
Peter Cordes
2
C'est moins une limitation de sudo que vous travaillez et plus une limitation de l'interprétation de shell par>. Lorsque vous exécutez une commande avec sudo, sa sortie standard est renvoyée à votre programme shell et les redirections supplémentaires avec> sont exécutées avec les autorisations du shell. Si vous souhaitez écrire avec des autorisations élevées, vous devez définir la partie élevée du pipeline. Il existe un grand nombre de façons de procéder, en fonction de l’effet recherché. Si vous voulez vraiment utiliser quelque chose comme 'sudo bash -c "commande> outfile"' fera le travail.
Perkins
Exactement, @Perkins. La coque du parse >et met en place la redirection avant même obtenir sudo exec« d, il est donc certainement pas une limitation de sudo qu'il ne gère pas les choses qu'il ne voit jamais. :) J'essaie généralement de parler de "flux de travail sudo" ou d'un terme similaire lorsque je l'explique, plutôt que de décrire sudo lui-même.
dannysauer
sudo tee -aIMHO est un abus de tee. Utilisez sudo cat, sudo ddou (avec les meilleures performances dans de nombreux cas) sudo buffersi vous n'avez pas besoin les multiples sorties.
Eugen Rieck
70

C'est pratiquement la même chose et il faut moins de frappes au clavier pour taper.

Ce n'est pas la même chose du tout ...

Les éléments suivants semblent être quelque peu équivalents, mais ils ne le sont pas:

$ echo "hi" > test.txt
$ echo "hi" | tee test.txt
hi

La différence critique est que le premier a écrit les données uniquement dans le fichier nommé, tandis que le dernier a écrit hidans le terminal ( stdout) et dans le fichier nommé, comme indiqué ci-dessous:

redirection vs tee


teevous permet d'écrire les données dans un fichier et de les utiliser dans un pipeline ultérieur, vous permettant de réaliser des tâches utiles, telles que la conservation des données à mi-chemin d'un pipeline:

grep '^look ' interesting_file.txt \
  | tee interesting_lines.txt \
  | sort

Ou bien, vous pouvez écrire dans un fichier avec des privilèges élevés, sans donner à l'ensemble du pipeline les privilèges élevés (ici, il echoest exécuté en tant qu'utilisateur, alors qu'il est teeécrit dans le fichier root):

echo 0 \
  | sudo tee /proc/sys/net/ipv4/ip_forward

Avec tee, vous pouvez écrire dans de nombreux fichiers ( et stdout ):

echo "hi" \
  | tee a.txt b.txt

Il est également possible d'utiliser execavec teepour enregistrer toute la sortie d'un script dans un fichier, tout en permettant à un observateur ( stdout) de voir les données:

exec > >( tee output.log )
Attie
la source
2
Ne pas oublier exec > >(tee "$LOGFILE") 2>&1dans un script bash qui permet au script de sortir stdout et stderr à la fois, stdout et le fichier pointé par $LOGFILE.
rexkogitans
@rexkogitans 2> & 1 n'est-ce pas la syntaxe de batch cmd?
dmb
@dmb: C'est la syntaxe du shell pour "envoyer stderr (= 2) au même endroit que stdout (= 1)"
psmears le
@rexkogitans C'était vraiment une bonne question, je ne peux pas vraiment savoir que vous n'avez pas utilisé "Windoze" depuis une décennie. J'utilise 2>&1pour supprimer la sortie et err à txt les fichiers dans Windows.
dmb
1
@ dmb je suis désolé d'avoir l'air impoli. Tout est dans le commentaire de psmears. Évidemment, Windows a adopté le style Unix ici.
rexkogitans
27

C'est un tee:
entrez la description de l'image ici

Un raccord de tuyau en forme de T. Il a une entrée et deux sorties séparées.
En d'autres termes, il divise un tuyau en deux; comme une fourchette dans la route.

De même, teeun pipe ( |) vous permet de rediriger votre entrée standard vers deux sorties distinctes.


Exemple
Dites par exemple, vous tapez ls /.
Vous obtiendrez une sortie qui ressemble à quelque chose comme:

Applications    Network     Users       bin        dev      net      private    tmp         var
Library         System      Volumes     cores      etc      home     opt        sbin        usr

Redirige la sortie dans un fichier texte ls / > ls.txt, et aucune sortie n'est affichée dans le shell, uniquement dans le fichier texte obtenu.

Voulez-vous voir la sortie ET le transférer dans un fichier texte en même temps?
Ajoutez un teeà votre pipe ( |) c'est à dire:ls / | tee ls.txt


Comparez les deux:

ls /          >          ls.txt
ls /        | tee        ls.txt
voix
la source
4
+1 pour l'image qui, comme nous le savons, vaut mille mots
Sergiy Kolodyazhnyy
Si vous aviez choisi une pièce en T de tuyau d'arrosage de jardin, vous auriez été conforme à la métaphore originale de Doug McIlroy.
JdeBP
@ JdeBP Désolé, je n'ai aucune idée de qui il s'agit. Est-il l'auteur original de l'utilitaire ou quelque chose? Le flux de données et le courant électrique physique sont souvent comparés aux systèmes hydrauliques, mais vous le savez probablement. Quoi qu'il en soit, j'ai juste choisi ce style pour le garder super simple. En fait, j'allais faire cela pour que cela reste familier, mais la variété de jardin a tendance à avoir davantage d'attaches en forme de Y et / ou visuellement compliquées pour attacher des accessoires, etc. C'est essentiellement la même chose.
voix
18

Non . Vous arrive de mentionner l' un des rares exemples où l' on pouvait en effet rediriger vers le fichier à l' aide >et les >>opérateurs.

Mais Tee peut faire beaucoup plus. Parce que vous le dirigez, vous pouvez alors passer à autre chose.

Un bon exemple est listé sur la page wikipedia :

find "4DOS" wikipedia.txt | tee 4DOS.txt | sort > 4DOSsorted.txt

Fondamentalement, vous pouvez diriger le tuyau vers Tee, vous pouvez donc diriger le tuyau de Tee vers autre chose. Si tout ce que vous voulez, c’est écrire un fichier journal, alors vous n’avez pas vraiment besoin de Tee.

LPChip
la source
17

teeest loin d'être inutile. Je l'utilise tout le temps et je suis content qu'il existe. C'est un outil très utile si vous souhaitez séparer un pipeline. Un exemple très simple est que vous avez un répertoire $dque vous voulez tarer et que vous voulez aussi le hacher parce que vous êtes paranoïaque (comme moi) et ne faites pas confiance au support de stockage pour conserver les données de manière fiable. Vous pouvez d'abord l' écrire sur le disque, puis le hacher, mais cela échouera si l'archive est corrompue avant d'être hachée. De plus, vous devrez le lire et si vous travaillez sur des fichiers de plusieurs centaines de Go, vous saurez que vous ne voulez vraiment pas les relire si ce n'est pas nécessaire.

Donc, ce que je fais est simplement ceci:

tar -c "$d" | tee >(sha256sum) >(cat > "$d"".tar") > /dev/null

Il crée la boule de goudron et la dirige vers le té, qui la dirige ensuite vers deux sous-coques, l'une dans laquelle elle est hachée et l'autre dont elle est écrite sur le disque.

C'est également intéressant si vous souhaitez effectuer plusieurs opérations sur un gros fichier:

< file.tar.gz tee >(sha256sum) >(tar -xz) /other/storage/location/file.tar.gz > /dev/null

Lit le fichier une fois, le hachait (afin que vous puissiez vérifier s'il est toujours comme il se doit), l'extrait et le copie dans un emplacement différent. Pas besoin de le lire trois fois pour ça.

UTF-8
la source
3
Nitpick: teene crée pas les sous-coques; le shell appelant s'exécute sha5sumet catconnecte sa sortie aux descripteurs de fichier auxquels il est transmis tee. En outre, une utilisation inutile de cat; vous pouvez utiliser la redirection d’entrée pour avoir teelu directement depuis file.tar.gz.
Chepner
@ chepner Vous avez raison à propos de la première intervention, mais vous vous trompez complètement à propos de la seconde. J'aime écrire mes pipelines dans l'ordre. Par conséquent, la lisibilité de l'entrée à droite est terrible pour la lisibilité. Cela est clairement objectivement inférieur à ma méthode et ne constitue en aucun cas une de mes préférences subjectives. catc'est l'amour. catc'est la vie.
UTF-8
6
Vous pouvez également écrire < file.tar.gz tee >(sha256sum) ...si vous êtes préoccupé par l'ordre lexical des redirections. Cela ne change pas le fait qu'il n'est pas nécessaire de mettre en place un processus entièrement séparé pour simplement alimenter un seul fichier tee.
Chepner
1
@chepner Cool, merci! J'ai appris quelque chose aujourd'hui. :)
UTF-8
1
Le coût de démarrage cat est relativement faible. Le coût de 100 GiB supplémentaires d’appels système écriture + lecture fait définitivement perdre un temps processeur supplémentaire et une bande passante mémoire supplémentaire à votre exemple de fichier volumineux. N'oubliez pas que la bande passante mémoire est une ressource partagée entre tous les cœurs, sans parler de la pollution supplémentaire du cache N3 résultant de cette copie. Sur un x86 avec l’atténuation Spectre + Meltdown activée, les appels système sont plus coûteux qu’auparavant. Vous utilisez une quantité mesurable de temps processeur supplémentaire au cours de cette copie. Aussi >(cat > foo)n'est pas plus facile à comprendre que foo, IMO.
Peter Cordes
12

Nitpick sur la réponse de @ bertieb disant: Cet exemple montre que le tee est utilisé pour contourner une limitation inhérente à la commande sudo. sudo ne parvient pas à diriger la sortie standard vers un fichier.

Il n'y a pas de limitation inhérente, seulement un malentendu sur le traitement de la commande.

Exemple:

sudo echo 0 > /proc/sys/net/ipv4/ip_forward

Le shell actuel analyse la ligne de commande. Il trouve la redirection de sortie et l'exécute. Ensuite, il exécute la commande, qui est le sudoet fournit la ligne de commande restante en tant qu'arguments à la commande exécutée. Si le shell actuel ne dispose pas des autorisations root, la redirection de sortie échouera.

echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward

Cela fonctionne parce que la redirection de sortie est reportée à la teecommande, qui à ce stade dispose des autorisations root car elle a été exécutée via sudo.

sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"

Cela fonctionne car le shell effectuant la redirection dispose des autorisations root.

studog
la source
2
En outre, vous aurez peut-être besoin sudode la commande, mais pas du fichier en sortie et la redirection fonctionne parfaitement:sudo foo-needs-privilege > /tmp/this-output-file-doesnt
Dennis Williamson
10

Comme d'autres personnes l'ont mentionné, la sortie de tuyauterie dans la teecommande écrit cette sortie à la fois dans un fichier et dans la sortie standard.

J'utilise souvent teelorsque je veux capturer la sortie d'une commande dont l'exécution est longue, tout en souhaitant également inspecter visuellement la sortie lorsque la commande la rend disponible. De cette façon, je n'ai pas besoin d'attendre la fin de l'exécution de la commande avant d'inspecter la sortie.

Ce qui ne semble pas encore avoir été mentionné (à moins que je ne l'aie pas manqué), c'est que la teecommande peut également écrire dans plusieurs fichiers à la fois. Par exemple:

ls *.png | tee a.txt b.txt

écrira tous les *.pngfichiers du répertoire en cours dans deux fichiers différents ( a.txtet b.txt) à la fois.

En fait, vous pouvez taper du texte dans plusieurs fichiers différents à la fois avec teececi:

$ tee --append a.txt b.txt c.txt d.txt
These lines are appended to four different files,
and are also written to stdout.
CTRL-D
JL
la source
9

L’utilisation la plus courante de tee est de voir le texte sur le terminal en même temps que vous l’envoyez au fichier (ou aux fichiers). Le libellé de votre question suppose que vous n’écrivez jamais que du texte dans les fichiers journaux. J'ai des scripts qui écrivent des listes de noms de fichiers ou de noms de répertoires pour déclencher des fichiers (à traiter par d'autres scripts de manière asynchrone) et j'utilise tee pour envoyer le même contenu à stdout. Toute la sortie standard est dirigée vers les journaux. Donc, j'ai mon texte où je le veux et j'ai une entrée de journal enregistrant que je l'ai fait, le tout à partir d'une seule déclaration 'echo'

tee est également la meilleure méthode sous Unix pour créer plusieurs fichiers identiques. Je l'utilise occasionnellement pour créer plusieurs fichiers vides, comme celui-ci ...

:|tee file01 file02 file03
Wil Young
la source
5
pourquoi pas touch? (plus immédiatement évident ce qui se passe)
Attie
@Attie touchne tronque pas les fichiers s'ils existent déjà, mais met à jour leur horodatage et laisse leur contenu tel quel ; mais teeva les tronquer. De plus, faire rm+ touchest différent de tee(pensez aux liens durs et aux liens symboliques)
Matija Nalis le
Alors , pourquoi pas truncate -s 0? :-)
Attie le
1

Imaginez, vous voulez écrire le résultat d’une commande dans un fichier journal ET l’ imprimer sur stdout. Lorsque vous avez besoin de le faire en même temps, alors vous en avez besoin tee.

Un cas d'utilisation consiste à créer des scripts qui écrivent l'intégralité de la construction sur stdout (par exemple pour Jenkins), mais également d'importants éléments en même temps dans un fichier journal séparé (pour les courriels récapitulatifs).

Vous allez vraiment commencer à manquer teelorsque vous devez écrire un script dans Windows. Il n'y a pas teeet c'est vraiment ennuyeux.

domih
la source
N'est-ce pas trivial de créer?
Courses de légèreté en orbite
Ce n'est pas possible avec batch / cmd car vous ne pouvez pas séparer facilement un flux de sortie d'une commande.
dimanche
Bien, mais comme un programme C ++ à trois lignes ...
Courses de légèreté en orbite
1
La distribution Windows unxutils comporte de nombreux outils de ligne de commande Unix qui, contrairement à certaines distributions, ne polluent pas votre environnement d'exécution Windows. La plus grande limitation concerne "glob", qui fonctionne différemment sous Unix / Linux et sous Windows. "tee" est parmi les outils disponibles.
cmm
2
Ne soyez pas stupide, nous sommes en 2018. Utilisez Powershell tee. Cmd n'a jamais été conçu pour des scripts sérieux - c'est à cela que servait VBS. Powershell est le nouvel outil de script à utiliser. Certes, Cmd est toujours assez puissant, mais les outils en ligne de commande sont assez peu nombreux.
Luaan