Différence entre 2> & -, 2> / dev / null, | &, /> / dev / null et> / dev / null 2> & 1

192

Je cherche juste la différence entre

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

et leur portabilité avec non-Bourne shellscomme tcsh, mksh, etc.

Det
la source
2
Notez que, bien que mksh prenne en charge la &>compatibilité GNU bash, il est vivement recommandé de ne pas l'utiliser, car son analyse peut casser la sémantique des scripts POSIX existants, et mksh le désactive déjà en mode POSIX.
mirabilos
J'ai aussi vu à ^ /dev/nullquoi ça sert?
Balupton

Réponses:

241

Pour le fond:

  • un nombre 1 = sortie standard (c.-à-d. STDOUT)
  • un nombre 2 = erreur standard (c.-à-d. STDERR)
  • si un nombre n'est pas explicitement donné, le numéro 1 est supposé par le shell (bash)

D'abord abordons la fonction de ceux-ci. Pour plus d'informations, reportez-vous au document Advanced Bash-Scripting Guide .

Les fonctions

2>&-

La forme générale de celui-ci est M>&-"M" est un numéro de descripteur de fichier. Ceci fermera la sortie pour le descripteur de fichier référencé, c'est-à-dire "M" .

2>/dev/null

La forme générale de celui-ci est M>/dev/null"M" est un numéro de descripteur de fichier. Cela redirigera le descripteur de fichier, "M" , vers /dev/null.

2>&1

La forme générale de celle-ci est M>&N"M" et "N" sont des numéros de descripteur de fichier. Il combine la sortie des descripteurs de fichier "M" et "N" en un seul flux.

|&

Ceci est juste une abréviation de 2>&1 |. Il a été ajouté dans Bash 4.

&>/dev/null

Ceci est juste une abréviation de >/dev/null 2>&1. Il redirige le descripteur de fichier 2 (STDERR) et le descripteur 1 (STDOUT) vers /dev/null.

>/dev/null

Ceci est juste une abréviation de 1>/dev/null. Il redirige le descripteur de fichier 1 (STDOUT) vers /dev/null.

Portabilité vers non-bash, tcsh, mksh, etc.

Je n'ai pas beaucoup traité d'autres coquillages en dehors de cshet tcsh. Mon expérience avec ces 2 par rapport aux opérateurs de redirection de bash, est que bash est supérieur à cet égard. Voir la page de manuel tcsh pour plus de détails.

Parmi les commandes que vous avez demandées, aucune n'est directement prise en charge par csh / tcsh. Vous devrez utiliser différentes syntaxes pour créer des fonctions similaires.

slm
la source
Nous avons un gagnant. Mais alors il n'y a pas de différence de performance ou quelque chose du genre avec 2>&-vs 2>/dev/null(mis à part le fait que certains programmes "mal" écrits ne fonctionnent pas 2>&-correctement)?
Dét.
3
Il ne devrait y avoir aucune différence de performance.
slm
5
&>était au bashdépart (et casse la compatibilité entre Bourne et POSIX car cela signifie quelque chose de différent là-bas, bien qu'il soit peu probable qu'il soit touché). >&et |&viennent de (t)csh(et c'est leur seul moyen de rediriger stderr). Ils étaient présents zshdepuis le début et n’ont été ajoutés que récemment bash. Voir aussi rcpour des opérateurs mieux conçus.
Stéphane Chazelas
1
Mise à jour: à propos du problème de performances, cela est également confirmé ici: unix.stackexchange.com/questions/163955/…
Det
1
Bonjour @slm, merci pour le contact. Je suis content que mon repo n'ait pas changé (+2-2=0). Maintenant, pour la partie édition, je n'édite pas beaucoup, mais dans ce cas, je le ferais, car cela clarifie le fait que les données après l'opération seraient à N. Je vous ai lu répondre, et c'est très bien dans tous les aspects. Juste cette petite ambiguïté m'a fait réfléchir, c'est pourquoi l'édition. Mais ok, n'hésitez pas à le ré-ajouter ou le rejeter, comme vous le souhaitez. J'espère que je pourrais expliquer le point. Continuez votre bon travail.
Dr Beco
11

C'est pour rediriger le STDERR & STDOUT:

  • 2>/dev/null

    Rediriger STDERR vers / dev / null (empêcher l’apparition sur la console)

  • |&

    Rediriger STDERR et STDOUT vers STDIN de la commande canalisée (cmd1 | & cmd2)

  • &>/dev/null

    Rediriger les deux STDERR & STDOUT vers / dev / null (rien ne s'affiche sur la console)

  • >/dev/null

    Rediriger STDOUT vers / dev / null (seul STDERR est affiché sur la console)

  • 2>&-

    Est-ce pour fermer un descripteur de fichier utilisé avec la redirection

Ce sont toutes des méthodes de redirection standard pour les shells Bourne.

BriGuy
la source
4
|&et ne&>/dev/null sont pas portables.
Chris Down
4

Considérez ceci comme un addenda à la réponse sélectionnée. Vous voudrez peut-être savoir quelles formes sont POSIX et lesquelles ne le sont pas.

Deux formes POSIX sont impliquées:

2.7.2 Réacheminement de la sortie

Les deux formats généraux pour rediriger la sortie sont les suivants:

[n]> mot

[n]> | word

où n optionnel représente le numéro du descripteur de fichier. Si le numéro est omis, la redirection doit faire référence à la sortie standard (descripteur de fichier 1).

La redirection de sortie utilisant le format '>' doit échouer si l'option noclobber est définie (voir la description de l'ensemble -C) et que le fichier nommé par le développement du mot existe et est un fichier normal. Sinon, redirection à l'aide de '>' ou "> |" formats doit provoquer la création du fichier dont le nom résulte de l’extension du mot et son ouverture pour sortie sur le descripteur de fichier désigné, ou sortie standard si aucun n’est spécifié. Si le fichier n'existe pas, il doit être créé. sinon, il sera tronqué pour devenir un fichier vide après avoir été ouvert.

-

2.7.6 Dupliquer un descripteur de fichier de sortie

L'opérateur de redirection:

[n]> & word

doit dupliquer un descripteur de fichier de sortie d'un autre ou en fermer un. Si le mot correspond à un ou plusieurs chiffres, le descripteur de fichier désigné par n, ou la sortie standard si n n'est pas spécifié, doit être une copie du descripteur de fichier désigné par un mot; si les chiffres dans word ne représentent pas un descripteur de fichier déjà ouvert pour la sortie, une erreur de redirection entraînera; voir Conséquences des erreurs de shell. Si le mot est évalué à '-', le descripteur de fichier n ou la sortie standard si n n'est pas spécifié est fermé. Les tentatives de fermeture d'un descripteur de fichier qui n'est pas ouvert ne constituent pas une erreur. Si mot est évalué à autre chose, le comportement n'est pas spécifié.

Donc:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

La dernière ligne ne se trouve pas dans la question initiale, mais cela fonctionne sans problème en bash. (Fonctionne également avec / dev / tty substitué à / dev / null).

Craig Hicks
la source
1
Je veux toujours en savoir plus.
Det