web-dev-qa-db-fra.com

Quel est le but de 'tee'?

Tous les usages de tee que j'ai jamais vus étaient tels:

 do_something | tee -a logfile

Ou:

do_something_else | tee logfile

tee est-il inventé pour ceux qui ne savent pas que vous pouvez faire la même chose avec les redirections de tubes Shell? 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 dans tee?

87
R Moog

Ce que vous ne voyez pas, c'est que do_something | tee -a logfile place le résultat dans logfile et sur stdout, alors que do_something >> logfile le met seulement dans le fichier journal.

Le but de tee est 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 tee permet une utilisation plus simple de Sudo. Ceci est à côté du point: cat, dd ou peut-être mieux buffer fournir cette possibilité avec de meilleures performances, si vous n'avez pas besoin des sorties multiples. Utilisez tee pour ce qu'il est conçu et non pour ce qu'il "peut aussi faire"

241
Eugen Rieck

Tee n'est pas inutile

Peut-être que tu le savais quand même? Si non, lisez la suite! Ou si vous savez comment cela fonctionne, mais que vous n'êtes pas sûr de pourquoi il existe, passez à 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é assimilé à un pièce en té de plomberie de la manière dont il divise 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_something et l'ajoute au fichier journal, tout en l'affichant à l'utilisateur. En fait, le page Wikipedia sur tee a ceci comme 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 of permissions :

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 commande Sudo. Sudo ne parvient pas à 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 à Exemples d'utilisation de la commande Tee )

Tee fonctionne 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 à Les bases de la philosophie Unix )

tee convient à 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
119
bertieb

C'est pratiquement pareil 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 hi sur le terminal (stdout)etle fichier nommé, comme indiqué ci-dessous:

 redirect vs tee


tee vous permet d'écrire les données dans un fichier et l'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, vous pouvez écrire dans un fichier avec des privilèges élevés, sans donner à l'ensemble du pipeline les privilèges élevés (ici, echo est exécuté en tant qu'utilisateur, alors que tee écrit dans le fichier sous la forme root):

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

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

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

Il est également possible d'utiliser exec avec tee pour enregistrer toutes les sorties d'un script dans un fichier, tout en permettant à un observateur (stdout) de voir les données:

exec > >( tee output.log )
69
Attie

C'est un tee:
 enter image description here

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, tee est un canal (|) qui vous permet de rediriger votre entrée standard vers deux sorties distinctes.


Exemple
Disons par exemple que vous tapez ls /.
Vous obtiendrez une sortie ressemblant à 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, mais uniquement dans le fichier texte obtenu.

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


Comparez les deux:

ls /          >          ls.txt
ls /        | tee        ls.txt
26
tjt263

Vous avez peut-être mentionné l’un des rares exemples où vous pouviez effectivement rediriger vers le fichier à l’aide des opérateurs > et >>.

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

Un bon exemple est donné 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.

18
LPChip

tee est 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 $d que 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 pourriez écrivez-le d'abord sur le disque, puis hachez-le, mais cela échouerait si l'archive était 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 s'il ne le faut pas.

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 dans laquelle elle est écrite.

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.

17
UTF-8

Nitpick sur la réponse de @ bertieb disant Cet exemple montre que té 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 correspond à la variable Sudo, et 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 car la redirection de sortie est différée vers la commande tee 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.

12
studog

Comme d'autres personnes l'ont mentionné, la sortie de tuyauterie vers la commande tee écrit cette sortie dans un fichier et sur stdout.

J'utilise souvent tee lorsque je veux capturer le résultat d'une commande dont l'exécution est longue, tout en souhaitant également inspecter visuellement le résultat lorsque la commande le 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 commande tee peut également écrire dans plusieurs fichiers à la fois. Par exemple:

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

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

En fait, vous pouvez taper du texte dans plusieurs fichiers en même temps avec tee comme ceci:

$ 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
10
J-L

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
9
Wil Young

Imaginez que vous souhaitiez écrire le résultat d’une commande dans un fichier journalETprint sur la sortie standard. Lorsque vous devez le faire en même temps, vous avez besoin de 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 sur des éléments importants en même temps dans un fichier journal séparé (pour les courriels récapitulatifs).

Vous allez vraiment commencer à manquer tee lorsque vous devez créer un script dans Windows. Il n'y a pas de tee et c'est vraiment agaçant.

1
domih