envoi de la sortie vers / dev / stderr vs.> & 2

11

Dans les scripts, les erreurs sont généralement envoyées au descripteur de fichier 2 avec &2, c'est-à-dire:

echo "error" >&2

Parfois /dev/stderrest utilisé à la place:

echo "error" > /dev/stderr 

En regardant /dev/stderr, je vois que ce n'est qu'un lien symbolique vers /proc/self/fd/2, qui à son tour est un lien symbolique vers /dev/pts/5(sur mon terminal actuel).

Semble un peu trop compliqué. Y a-t-il une logique derrière cela?

Utilise /dev/stderret est &2équivalent?

Est-ce que l'un d'entre eux est préféré à l'autre?

Martin Vegter
la source
3
echo "error" >2crée un fichier avec nom 2et contenu error.
Cyrus
Je vois mon montage réintroduit & 2 au lieu de 2. Votre question concerne-t-elle réellement l'utilisation de >2, ou >&2?
Jeff Schaller

Réponses:

13

Le périphérique spécial /dev/stderrest spécifique au système, tandis que le descripteur de fichier 2(et non le périphérique spécial /proc/self/fd/2) est portable. Si vous souhaitez écrire du code non portable, ces appareils spéciaux sont un bon point de départ.

Il y a quelques systèmes avec /dev/stderr: Linux, bien sûr, et OSX . Mais OSX n'a ​​pas de /procsystème de fichiers, et /dev/stderrc'est un lien vers /dev/fd/2.

Lectures complémentaires:

Thomas Dickey
la source
Il y a aussi le cas où quelqu'un veut faire par exemple. ce 2> bla.logqui fonctionnerait aussi longtemps que vous dirigez vers 2et non du code dur /dev/stderr. Fondamentalement, il 2n'a pas besoin d'être la stderrsortie.
larkey
6

Dans bash, et d'autres shells, la façon de rediriger quelque chose vers l'erreur standard est d'utiliser >&2. Bash s'ouvre en /dev/stderrtant que descripteur de fichier 2 . Les descripteurs de fichiers sont référencés par &NNest le numéro du descripteur. Donc, echo error >&2imprimera errorà l'erreur standard, à /dev/stderr.

Il s'ouvrira également /dev/stdoutcomme descripteur de fichier 1. Cela signifie que vous pouvez le faire echo output >&1. Cependant, comme tout est imprimé sur la sortie standard de toute façon par défaut, c'est la même chose que echo outputpar lui-même.

Maintenant, 2>c'est différent. Ici, vous redirigez la sortie d'erreur d'une commande ailleurs. Donc, 2>filesignifie "rediriger tout ce qui est imprimé vers le descripteur de fichier 2 (erreur standard) vers file".

terdon
la source
3

Tu as raison, >&2c'est plus direct et parfaitement "idiomatique". Ils doivent être équivalents, il n'y a donc aucune raison particulière de les utiliser >/dev/stderr. Sauf que si quelqu'un qui lit ne sait pas ce que cela fait, l'un d'eux est probablement plus facile à découvrir que l'autre :-). Mais en général, je vous suggère d'utiliser >&2.

/ dev / stderr peut être utile lorsque les programmes écrivent des erreurs dans un nom de fichier spécifié, mais ne prennent pas en charge stderr. De toute évidence, c'est un peu artificiel; / dev / stdout est beaucoup plus utile. (J'ai récemment trouvé que le mysql_safescript wrapper n'écrirait pas d'erreurs sur la console; malheureusement, il souhaite également modifier les autorisations sur le fichier journal des erreurs, donc l'utilisation de / dev / stderr provoque quelques avertissements superflus).

sourcejedi
la source