quelle est la difference entre `>> / dev / stderr` (avec l'espace blanc) et`> & 2`?

11

En bash.

J'ai du mal à déterminer ce que je devrais utiliser?

tous mes scripts utilisent ">> / dev / stderr"

à l' invite bash, si je tente:
echo test >>/dev/stderrtravaux
echo test >> /dev/stderrtravaux
echo test >/dev/stderrtravaux
echo test > /dev/stderrtravaux

echo test >>&2ÉCHOUE!
echo test >> &2ÉCHOUE!
echo test >&2fonctionne
echo test > &2FAILS!

Je souhaite changer tous mes scripts en >&2.

Il semble également avoir un grand effet sur ssh (après su SomeUser) où >>/dev/stderrne fonctionnera pas du tout (autorisation refusée), seulement >&2fonctionnera.

Puissance du Verseau
la source
pouvez-vous montrer un exemple de l'erreur ssh? Je ne peux pas le reproduire.
Jeff Schaller
@JeffSchaller vous avez raison, ce n'est qu'après suque le problème se produit, a mis à jour la question
Aquarius Power
@AquariusPower, ... pour expliquer cette différence, soit dit en passant: avec su -c 'some command', cette commande est exécutée par /bin/sh, non bash, donc le comportement spécifique à bash (comme la simulation /dev/stderrà des fins de redirection lorsqu'elle n'est pas disponible) n'est pas garanti d'être présent.
Charles Duffy

Réponses:

22

>& nest la syntaxe du shell pour dupliquer directement un descripteur de fichier . Le descripteur de fichier 2 est stderr; c'est comme ça que ça marche. Vous pouvez également dupliquer d'autres descripteurs de fichiers, pas seulement stderr. Vous ne pouvez pas utiliser le mode d'ajout ici car la duplication d'un descripteur de fichier ne tronque jamais (même si votre stderr est un fichier) et >&est un jeton, c'est pourquoi vous ne pouvez pas y mettre d'espace - mais cela >& 2fonctionne.

>> nameest une syntaxe autorisée différente, où nameest un nom de fichier (et le jeton est >>). Dans ce cas, vous utilisez le nom de fichier /dev/stderr, qui, par une gestion spécifique au système d'exploitation (sous Linux, c'est un lien symbolique /proc/self/fd/2), signifie également une erreur standard. Les modes ajouter et tronquer finissent tous les deux par faire la même chose lorsque stderr est un terminal car cela ne peut pas être tronqué. Si votre erreur standard est un fichier, cependant, il sera tronqué:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

Si vous voyez une erreur avec /dev/stderrover ssh, il est possible que l'administrateur du serveur ait appliqué une mesure de sécurité empêchant ce lien symbolique de fonctionner. (Par exemple, vous ne pouvez pas accéder à /procou /dev). Bien que je m'attende à ce que cela cause toutes sortes de bris étranges, l'utilisation de la syntaxe de descripteur de fichier en double est une approche parfaitement raisonnable (et probablement légèrement plus efficace). Personnellement je le préfère.

derobert
la source
J'avais beaucoup de mal à essayer de reproduire ce problème tronqué que j'avais auparavant (sinon j'aurais ajouté cela à la question hehe), la raison pour laquelle j'ai tout changé à utiliser >>, merci de le signaler! De plus, j'ai raté une étape su SomeUseraprès la connexion via ssh.
Aquarius Power
cela bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/foone tronquera pas tho! (même avec 2>&1 |tee /tmp/foo) ce qui est parfait pour la journalisation, et fonctionnera parfaitement après avoir tout changé >&2. Donc je suppose que seule une utilisation directe des fichiers /dev/stderrpermet de tronquer, pas le descripteur dupliqué, cool thx!
Aquarius Power
@AquariusPower correct, le descripteur de fichier en double n'est jamais tronqué. C'est dans le premier paragraphe, peut-être que je dois le souligner d'une manière ou d'une autre?
derobert
pas nécessaire, je suis parfois lent ehehe
Aquarius Power
3
Cette réponse peut être améliorée. > & est un jeton et non deux et il y a dans la confusion d'OP.
Joshua
8

Les cas d'échec se produisent parce que la syntaxe bash pour l'utilisation &dans les redirections spécifie un seul >et requiert qu'il existe directement à côté du &signe:

[n]> & mot

Jeff Schaller
la source
2

Utilisez '>'pour rediriger (tronque s'il existe) ou '>>'(ajoute s'il existe).

Utilisez '>&'pour dupliquer un flux, par exemple, si vous voulez une sortie standard ET une erreur standard dans le même fichier, vous redirigez vers le fichier '> output.log'et aussi une erreur avec'2>&'

myjob.sh > output.log 2>&
Jose Manuel Gomez Alvarez
la source