web-dev-qa-db-fra.com

Pourquoi rediriger la sortie vers 2> & 1 et 1> & 2?

Je suis tombé sur plusieurs commandes qui utilisent 2>&1 et 1>&2, mais je ne peux vraiment pas comprendre le but de l’utiliser ni le moment où je devrais l’utiliser.

Ce que je comprends

Je sais que 1 représente la sortie standard et 2 représente l'erreur standard. Je comprends que 2>&1 combine le résultat de 2 à 1 et vice versa.

Ce que je ne comprends pas

  1. Quand devrais-je l'utiliser?
  2. A quoi cela sert-il?
33
PeanutsMonkey

Parfois, vous souhaitez rediriger stdout et stderr vers le même emplacement. C’est lorsque >& est utilisé - il pointe un descripteur de fichier vers un autre.


Par exemple, si vous voulez écrire stdout et stderr dans le même fichier (que ce soit /dev/null ou output.txt), vous pouvez les rediriger séparément, avec

app 1>/dev/null 2>/dev/null

ou vous pouvez rediriger un descripteur de fichier vers le fichier et l’autre descripteur de fichier dans le premier:

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

Dans le premier exemple, 2>&1 pointe le descripteur de fichier n ° 2 sur le pointeur n ° 1. Le deuxième exemple obtient le même résultat, en commençant par stderr.

Autre exemple, il existe des cas où stdout (descripteur de fichier n ° 1) pointe déjà vers l'emplacement souhaité, mais vous ne pouvez pas y faire référence par son nom (il peut être associé à un tuyau, à un socket, etc.). Cela se produit souvent lorsqu’on utilise l’extension de processus (les opérateurs ` ` ou $( )), qui ne capture normalement que stdout, mais vous voudrez peut-être y inclure stderr. Dans ce cas, vous utiliseriez également >& pour pointer stderr sur stdout:

out=$(app 2>&1)

Un autre exemple courant est un pager, ou grep, ou un utilitaire similaire, puisque le tube | ne fonctionne normalement que sur stdout; vous redirigeriez stderr vers stdout avant d'utiliser le canal:

app 2>&1 | grep hello

Comment savoir lequel de 2>&1 ou 1>&2 est correct? Le descripteur de fichier déjà configuré se place à droite de >& et le descripteur de fichier que vous souhaitez rediriger se place à gauche. (2>&1 signifie "descripteur de fichier de point n ° 2 au descripteur de fichier n ° 1".)


Certains shells ont des raccourcis pour les redirections courantes; voici des exemples de Bash:

  • 1> peut être réduit à seulement >

  • 1>foo 2>&1 à >&foo ou &>foo

  • 2>&1 | program à |& program

36
grawity

Parfois, vous souhaitez rediriger stdout (1) et stderr (2) vers le même emplacement (/dev/null, par exemple). Un moyen d'y parvenir serait:

$ program 1>/dev/null 2>/dev/null

Mais la plupart des gens raccourcissent cela en redirigeant stderr vers stdout avec 2>&1:

$ program 1>/dev/null 2>&1

Une version encore plus courte est:

$ program >&- 2>&-
2
Zaz

Lorsque vous en avez besoin, vous pouvez par exemple afficher la sortie strace dans un pager. strace affiche sa sortie en erreur standard et les tuyaux connectent généralement la sortie standard à entrée standard, vous devez donc utiliser la redirection:

strace -p $pid 2>&1 | less
2
jpalecek

2: C'est pour quand vous aurez une sortie venant à la fois d'erreur standard et standard, et que vous voulez les composer en une seule chaîne.

1: Lorsque vous voulez manipuler la sortie d'erreur standard et sortie standard.

1
soandos

Le cas de la redirection de stderr sur stdout a déjà été traité ici (par exemple, utilisez-le pour filtrer les messages d'erreur (grep)).

L'autre cas est la redirection de stdout vers stderr. Un cas d'utilisation courant (du moins pour moi) consiste à envoyer des avertissements/messages d'erreur avec "echo" (dans mes scripts de shell) au stderr (afin qu'ils puissent attirer plus facilement l'attention de l'utilisateur).

Par exemple,

echo "file \"${file\" does not exist..." 1>&2
0
umläute

Scénario alternatif: les commandes du terminal affichent la sortie dans un autre terminal

Utilisez la commande tty dans chaque terminal pour les identifier:

$ tty
/dev/pts/0

$ tty
/dev/pts/1

En supposant que ces TTY, pour rediriger la sortie standard du premier à la seconde, exécutez ceci dans le premier terminal:

exec 1>/dev/pts/1

Remarque: Maintenant chaque sortie de commande s'affichera sur pts/1

Pour restaurer le comportement par défaut de la sortie standard de pts/0:

exec 1>/dev/pts/0

Voir cette vidéo pour une démonstration.

0
Vitalie Ghelbert

Je l'utilise pour commencer un travail détaché:

someProgram 2>&1 >& my.log &

alors je peux me déconnecter, et someProgram sera toujours en cours d'exécution. La fonctionnalité est fournie par GNU Screen, tmux et quelques autres programmes - mais ici, elle est réalisée sans aucune dépendance externe.

0
Adobe

Imaginez qu’il existe un répertoire nommé try qui contient ces trois fichiers: file file1 and file2.

Maintenant, lancez cette commande:

cat file file1 file2 file3

Les trois premiers fichiers sont ouverts mais cat génère une erreur lors de l’ouverture du quatrième, car il n’existe pas.

Maintenant, lancez:

cat file file1 file2 file3 1>outfile 2>&1

Vous ne verrez aucune sortie à l'écran. Tout d'abord, 1>outfile redirige la sortie de la commande vers outfile, puis redirigera (2>&1) l'erreur renvoyée lors de la tentative d'ouverture de file3 à outfile.

1>&2 fonctionne de manière similaire et redirige le flux d’erreurs vers la sortie standard.

J'espère que cela t'aides!

0
Faiz