Comment pourrais-je me rappeler comment utiliser la redirection?

40

Je sais ce que

  program > /dev/null 2>&1 

Est-ce que. Il redirige la sortie vers /dev/nullet 2>&1signifie pour rediriger la sortie d'erreur au même endroit où la sortie est envoyée.

Mon problème est que je dois toujours google parce que je ne m'en souviens jamais.

Alors, j'essaie &2>1, 1>2&, 1>&2... J'essaie toutes les combinaisons jusqu'à ce que je google ...

Quelle est l'astuce pour s'en souvenir facilement?

Luc M
la source
J'ai le même problème, donc je le fais par le "long" chemin - redirige les deux program 1> /dev/null 2>/dev/null. Il arrive parfois que vous ayez besoin de mélanger les éléments stdoutet stderrensemble pour voir ce qui se passe réellement - par exemple, la sortie d’un processus de compilation complexe redirigé vers un fichier. Dans ce cas, je
finis par googler

Réponses:

20

La sortie est meilleure que l’erreur alors c’est la première (1 vs 2).

>est un raccourci pour «va à». À gauche, ce que je veux envoyer et à droite, où je veux l'envoyer. Puisque 'où' est (presque) toujours un fichier, quelque chose comme

program > /dev/null 2>1

serait redirigé vers un fichier nommé 1. Ainsi, l'esperluette (&)modifie le descripteur de fichier à fichier.

Malheureusement, je n'ai pas encore développé ni développé ma propre mnémonique, mais lorsque j'ai appris * nix pour la première fois, j'ai trouvé cette façon logique de bien travailler. Après quelques essais, cela devient une seconde nature.

gvkv
la source
Votre première phrase n'a pas de sens pour moi. stdoutest le descripteur de fichier 1, stderrest 2. Donc, "erreur" vient avant "sortie".
Warren Young
Cette phrase est un mnémonique pour rappeler quel descripteur de fichier stdoutet se stderrréférer.
Gvkv
D'accord, mais cela semble toujours déroutant, car la question initiale visait à essayer de rappeler l'ordre des caractères dans l'incantation "2> & 1".
Warren Young
9

Une astuce consiste simplement à se rappeler que 1 = sortie standard, 2 = erreur standard. Alors:

2>&1= le flux d'erreur standard entre dans le flux de sortie standard.
1>&2= vice versa.

Si vous avez déjà programmé dans une langue semblable à C, il est facile de se souvenir de l'esperluette ( &). J'ai choisi d'y penser comme faisant référence à "l'adresse du" descripteur de fichier existant, afin que vous ne modifiiez pas le fichier lui-même ni n'en créiez un nouveau.

Thronic
la source
7

Voir le &nœud peut aider: pensez à ce que vous voulez faire en prenant la sortie de 2, donc 2>, et en la liant avec 1, donc2>&1

Bertrand Lorentz
la source
2
Je viens de mémoriser la phrase "deux sur et un". Que votre mnémonique soit une phrase ou un nœud, en avoir une vous aidera vraiment.
Tim Kennedy
5

En fait, cela dépend du shell que vous utilisez. Bash est généralement très tolérant et vous pouvez simplement faire:

program &> file
Kevin Cantu
la source
5

Considérons ces trois options:

program  2>1
program  2>1& 
program  2>&1

Le premier envoie stderr à un nom de fichier "1": après tout, bash s'attend à être redirigé vers un fichier.

La seconde redirige également vers le même fichier mais s’exécute programen arrière-plan: c’est ce qu’un &supposé est supposé vouloir dire.

Cela laisse la troisième possibilité comme la seule à avoir un sens dans l'univers bash pour la redirection vers un descripteur de fichier.

Comment se rappeler lequel est lequel parmi 0, 1, 2? Pensez à faire fonctionner un ordinateur à partir de la console. Tout d'abord, vous devez taper quelque chose (0 = stdin). Ensuite, vous voyez la sortie (1 = stdout). Enfin et seulement si quelque chose ne va pas, vous voyez stderr (2).

John1024
la source
1

Dessine-le dans ton fond d'écran.

Maintenant, sérieusement, ceci et d'autres éléments de base que je ne cessais d'oublier, j'ai donc ajouté un menu de conseils rapides à une application que j'ai développée et que j'utilise quotidiennement. Vous voudrez peut-être essayer ou utiliser quelque chose comme gnote pour conserver une note.

Ubersoldat
la source
1

En ce qui concerne le shell bash, je trouve que la meilleure façon de se souvenir est de comprendre ce qui se passe.
Si tout ce que vous voulez faire est de vous rappeler comment obtenir la commande correcte, vous pouvez essayer

program > /results 2> /results

C'est beau et évident ce qui se passe et facile à retenir. c'est à dire

  • 1 STDOUT va /results
  • 2STDERR se rend également directement à/results

le problème est que cela ne fonctionne pas comme prévu. considérer ce qui suit:

fichier: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

et exécutez la commande

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

puis

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

que s'est-il passé ici?
Je crois comprendre que bash configure la redirection pointant le STDERR directement vers le fichier /tmp/resultset en raison de la nature de >ce qui fait 2 choses

  1. normalement créer un nouveau fichier - dans ce cas, l'opportunité est passée, bash dépassant cette routine au moment de la génération de la sortie.
  2. insérer directement au début du fichier. et ne pas ajouter comme >>fait.

Donc, dans ce cas, STDERR, insère directement au début du /tmp/resultsremplacement de la sortie de STDOUT.
Remarque: si vous aviez l'habitude >>d'ajouter, vous pourriez probablement vous en tirer avec cette syntaxe.
Cependant, pour résoudre le problème dont vous avez besoin - non pas pour rediriger STDERR - directement vers le fichier, mais plutôt pour fusionner la sortie de STDERR dans le flux STDOUT, afin d'éviter toute collision.
En utilisant l'opérateur, l' 2>&1opérateur réalise ceci

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

Le &permet bash de distinguer d'un fichier nommé 1et le 1descripteur de fichier.
Pour moi, la déclaration 2>&1elle-même explique exactement ce qui se passe - STDERR est redirigé vers STDOUT lui-même - et ne se termine que /tmp/resultsparce que c'est là que STDOUT est pointé (presque comme un effet secondaire).
Contrairement à ce que beaucoup de guides affirment, c’est-à-dire que 2>&1STDERR est envoyé partout où STDOUT est pointé. Si cela était vrai, vous auriez toujours le problème de réécriture.

Pour plus d'informations, voir http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

the_velour_fog
la source