2010-10-18 34 views
4

De this perldoc page,Comment fonctionnent ces redirections de flux?

  1. Pour capturer STDERR et STDOUT une commande ensemble:

    $output = `cmd 2>&1`;
  2. Pour capturer STDOUT d'une commande jeter le STDERR:

    $output = `cmd 2>/dev/null`;
  3. Pour capturer une commande STDERR mais supprime son STDOUT (la commande est importante ici):

    $output = `cmd 2>&1 1>/dev/null`;
  4. Pour échanger STDOUT d'une commande et STDERR afin de capturer le STDERR mais laisser le STDOUT sortir l'ancien STDERR:

    $output = `cmd 3>&1 1>&2 2>&3 3>&-`;

Je ne comprends pas comment 3 et 4 travail, et je ne suis pas sûr de ce que je comprends à propos de 1 et 2 est juste. Voici ce que je comprends. S'il vous plaît, corrigez-moi là où j'ai tort.

Je sais que 0, 1 et 2 symbolisent STDIN, STDOUT et STDERR.

  1. redirect 2 à 1, de sorte que les deux utilisent le même flux maintenant (& se sont échappés 1 en vous assurant que STDERR ne sont pas redirigés vers un fichier nommé 1 à la place)

  2. redirect 2 (STDERR) à zéro flux, de sorte qu'il est rejeté

  3. Je ne comprends pas celui-ci. Ça ne devrait pas être juste

    $output = `cmd 1>/dev/null`;

    En outre, si le but est d'obtenir les messages STDERR à STDOUT, ne 1>/dev/null tout rediriger vers /dev/null?

  4. Que se passe-t-il ici? Quel est le flux 3? Est-ce comme une variable temporaire?

+0

@skaffman - pourquoi ajouter à nouveau le tag perl? La mention de perl n'est pas liée à la question. –

+0

@bemace: Mon mauvais – skaffman

Répondre

3

Vraiment, rien de tout cela est Perl - tout cela est géré par le shell que vous appeler en utilisant l'opérateur accents graves. Donc, votre meilleure lecture est man sh, ou le Shell chapter of the Unix standard.

En bref, bien que, pour # 4:

  • 3>&1: Open FD 3 au point où stdout pointe actuellement.
  • 1>&2: Rouvrez stdout pour pointer vers où pointe actuellement stderr.
  • 2>&3: Rouvrez stderr pour pointer vers où pointe actuellement FD 3, où stdout a pointé avant l'étape précédente a été terminée. Maintenant, stdout et stderr ont été échangés avec succès.
  • 3>&-: Fermez FD 3 car il n'est plus nécessaire.
+0

redirections sont affectés de gauche à droite, sont-ils? – Lazer

+0

@Lazer: c'est correct. –

+0

@Lazer oui ils sont. La norme en dit autant. :) – hobbs

-2

3.Non. L'ordre est important, donc il se débarrasse de la sortie d'origine, puis il déplace stderr à stdout.

4. 3 est juste un autre descripteur de fichier, identique au premier 3. La plupart des processus peuvent utiliser un total de 256 descripteurs de fichiers différents.

+0

"2> & 1 1>/dev/null" -> "... alors il déplace stderr sur stdout". Êtes-vous sûr? Cela n'arrive-t-il pas dans l'ordre inverse? – Lazer

+0

Les redirections s'effectuent de droite à gauche. –

+0

@Ignacio: Alors, comment ça marche dans ** 4 **? Cela voudrait dire que le flux 3 est fermé avant même d'avoir été ouvert! – Lazer

3

Bien que documentée dans les perldocs, la redirection est une redirection linux standard. Vous comprenez 1 et 2 correctement.

3) Seul STDOUT est normalement pris par une redirection de base (>), de sorte que le doit être mis au rebut STDOUT d'origine, et STDERR doivent être envoyés à STDOUT.

4) cmd 3>&1 1>&2 2>&3 3>&- est équivalent à

var tmp = STDOUT; 
STDOUT = STDERR; 
STDERR = tmp; 
delete tmp; 
3

Normalement, nous avons ceci:

1-->STDOUT 
2-->STDERR 

2>&1 réoriente descripteur de fichier fd2 à fd1

1-->STDOUT 
/
2./ 

2>/dev/null réoriente fd2-/dev/null.

1-->STDOUT 
2-->/dev/null 

2>&1 1>/dev/null redirige fd2 à fd1, et redirige ensuite fd1 à /dev/null

/dev/null 
/
1./ STDOUT 
/
2./ 

3>&1 1>&2 2>&3 3>&-

  1. premier dirige une nouvelle fd 3 à l'endroit où fd une pointe actuellement (STDOUT) .
  2. redirige ensuite fd1 à l'endroit où fd2 est pointage courant (stderr),
  3. redirige ensuite fd 2 à l'endroit où fd 3 pointe actuellement (STDOUT)
  4. ferme alors FD3 (3> & - signifie près fichier descripteur 3).

Le tout échange efficacement fd1 et fd2. fd3 a agi comme une variable temporaire.

1 --STDOUT 
X 
2 `-STDERR 

Voir the docs pour plus d'informations sur la redirection IO.