web-dev-qa-db-fra.com

Différence entre 2> & 1> output.log et 2> & 1 | tee output.log

Je voulais connaître la différence entre les deux commandes suivantes

2>&1 > output.log 

et

2>&1 | tee output.log

J'ai vu un de mes collègues utiliser la deuxième option pour rediriger. Je sais ce que fait 2> & 1, ma seule question est à quoi sert l'utilisation de tee où un simple opérateur de redirection ">" peut être utilisé?

36
Chander Shivdasani

En examinant les deux commandes séparément:

utility 2>&1 >output.log 

Ici, puisque les redirections sont traitées de gauche à droite, le flux d'erreur standard serait d'abord redirigé vers l'endroit où le flux de sortie standard va (peut-être vers la console), puis le flux de sortie standard serait redirigé vers un fichier. Le flux d'erreur standard serait pas redirigé vers ce fichier.

L'effet visible de ceci serait que vous obtenez ce qui est produit sur l'erreur standard à l'écran et ce qui est produit sur la sortie standard dans le fichier.

utility 2>&1 | tee output.log

Ici, vous redirigez l'erreur standard au même endroit que le flux de sortie standard. Cela signifie que les flux both seront dirigés vers l'utilitaire tee en tant que flux de sortie unique mélangé, et que ces données de sortie standard seront enregistrées dans le fichier donné par tee. Les données seraient en outre reproduites par tee dans la console (c'est ce que fait tee, il duplique les flux de données).

Le choix de l'un d'entre eux dépend de ce que vous souhaitez réaliser.

Notez que vous ne pourrez pas reproduire l'effet du deuxième pipeline avec simplement > (un péché utility >output.log 2>&1, ce qui enregistrerait à la fois la sortie standard et l'erreur dans le fichier en redirigeant d'abord la sortie standard vers output.log, puis redirige l'erreur standard vers l'endroit où la sortie standard va maintenant). Vous devrez utiliser tee pour obtenir les données dans la console ainsi que dans le fichier de sortie.


Notes complémentaires:

L'effet visible de la première commande,

utility 2>&1 >output.log 

serait le même que

utility >output.log

C'est-à-dire que la sortie standard va au fichier et l'erreur standard va à la console.

Si une étape de traitement supplémentaire était ajoutée à la fin de chacune des commandes ci-dessus, il y aurait cependant une grande différence:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

Dans le premier pipeline, more_stuff obtiendrait ce qui était à l'origine le flux d'erreur standard de utility en tant que ses données d'entrée standard, tandis que dans le deuxième pipeline, car ce n'est que le flux de sortie standard résultant qui est jamais envoyé via un tube, le more_stuff une partie du pipeline n'aurait rien à lire sur son entrée standard.

15
Kusalananda

Note éditoriale

Veuillez vous assurer de lire les commentaires sur cette réponse - derobert .


Réponse originale

2>&1 >output.log signifie d'abord commencer à envoyer tous les fichiers du descripteur 2 (erreur standard) au descripteur de fichier 1 (sortie standard) puis envoyer cela au fichier output.log. En d'autres termes, envoyez l'erreur standard et la sortie standard au fichier journal.

2>&1 | tee output.log est le même avec le 2>&1 bit, il combine la sortie standard et l'erreur standard sur le flux de sortie standard. Il dirige ensuite cela via le programme tee qui enverra son entrée standard vers sa sortie standard (comme cat) et aussi dans le fichier. Il combine donc les deux flux (erreur et sortie), puis les renvoie au terminal et au fichier.

L'essentiel est que le premier envoie stderr/stdout au fichier, tandis que le second l'envoie à les deux le fichier et la sortie standard (qui est = probablement le terminal sauf si vous êtes dans une autre construction qui a redirigé la sortie standard).

Je mentionne cette dernière possibilité parce que vous pouvez avoir des trucs comme:

(echo hello | tee xyzzy.txt) >plugh.txt

où rien ne se retrouve sur le terminal.

24
user14408

La première commande fera une autre tâche:

Après

2>&1 > output.log 

l'ancien STDOUT sera enregistré (copié) dans STDERR puis STDOUT sera redirigé vers le fichier.

Donc, stdout ira dans le fichier et stderr ira dans la console.

Et en

 2>&1 | tee output.log

les deux flux seront redirigés vers le tee. Tee dupliquera toute entrée dans sa sortie standard (la console dans votre cas) et dans le fichier (output.log).

Et il y a une autre forme de première:

    > output.log  2>&1

cela redirigera STDOUT et STDERR vers le fichier.

8
osgx

Le premier ne sort que dans le fichier. Le second renvoie à la fois au fichier et à l'écran.

4
André Caron

La raison pour 2>&1 | tee permet de capturer à la fois stdout et stderr dans un fichier journal et de le voir simultanément à l'écran. Cela pourrait être fait comme >output.txt 2>&1 & tail -f également, mais vous ne sauriez pas quand la commande en arrière-plan s'est terminée - le programme est-il terminé ou s'exécute-t-il sans sortie? Le 2>&1 | tee était un idiome courant pour les programmeurs.

4
Arcege

Voyons d'abord un exemple de code:

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

Permet de comparer les résultats:
./helloerror
+ fichier: aucun message; console: message 1,2,3;

./helloerror >error.txt
+ fichier: message 1,2; console: message 3;

./helloerror 2>&1 >error.txt
+ fichier: message 1,2; console: message 3;
+ identique à ./helloerror> error.txt

./helloerror >error.txt 2>&1
+ fichier: message 3,1,2; console: aucun message;
+ notez que l'ordre 3 est d'abord, puis 1, puis 2

./helloerror | tee error.txt 2>&1
+ fichier: message 1,2; console: message 3,1,2;
+ notez que l'ordre 3 est d'abord, puis 1, puis 2

./helloerror 2>&1 | tee error.txt
+ fichier: message 3,1,2; console: message 3,1,2;

Pour utiliser:
./helloerror >error.txt 2>&1
-> si l'on veut tous les messages (stdout + stderr) dans le fichier, mais pas affiché sur la console

./helloerror 2>&1 | tee error.txt
-> si l'on veut tous les messages (stdout + stderr) dans le fichier et imprimé sur la console

0
Hari Perev