Compréhension du pipeline et de la redirection

Veuillez expliquer ce script (extrait du chapitre 20 de l' ABSG ):

exec 3>&1 # Save current "value" of stdout. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not 'ls'). # ^^^^ ^^^^ exec 3>&- # Now close it for the remainder of the script 

Actuellement, j'imagine comment ça marche:

  1. script connecte la sortie fd / 3 à stdout
  2. pipeline connecte stdout de ls à stdin de grep (fd / 3 est hérité par les deux process)
  3. redirerection de stderr de ls à stdout
  4. stdout de ls est changé en fd / 3 (donc grep n'a plus de sortie ls , seulement des erreurs)
  5. fd / 3 est fermé pour ls

Est-ce la séquence exacte des redirections?

Je ne peux pas comprendre pourquoi je vois la sortie de ls s'il n'y a pas d'erreur et on ferme fd / 3 où stdout est redirigé.

Quel est le but de la fermeture de fd / 3 pour le process grep bad **3>&-** ( grep bad **3>&-** )?

Cela aide un peu si vous considérez les descripteurs de file comme des variables qui acceptent un file en tant que valeur (ou appelez-le un stream E / S) et l'ordre dans lequel ils apparaissent est l'ordre de leur évaluation.

Ce qui se passe dans l'exemple ci-dessus est:

1) Le script démarre (par défaut et à less d'être hérité) avec les éléments suivants

 fd/0 = stdin # that's the keyboard fd/1 = stdout # that's the screen fd/2 = stderr # the screen again, but different stream 

2) La command exec traduit par la déclaration d'une nouvelle variable et l'atsortingbution d'une valeur

 fd/3 = fd/1 # same as stdout 

Alors maintenant, deux descripteurs de file ont la valeur stdout, c'est-à-dire que les deux peuvent être utilisés pour imprimer à l'écran.

3) avant que ls soit exécuté et hérite de tous les descripteurs de files ouverts, l'installation suivante se produit

 ls.fd/1 = grep.fd/0 # pipe gets precedence, ls.fd/1 writes to grep.stdin ls.fd/2 = ls.fd/1 # ls.fd/2 writes to grep.stdin ls.fd/1 = ls.fd/3 # ls.fd/1 writes to stdout ls.fd/3 = closed # fd/3 will not be inherited by `ls` 

fd / 3 a servi à maintenir la valeur de stdout assez longtime pour la ramener à fd / 1. Alors maintenant, tout ce que ls envoie à fd / 1 va à stdout et non à stdin de grep .

La command est importante, par exemple si nous exécutons ls -l >&3 2>&1 3>&- , ls.fd / 2 écrira dans stdout au lieu de stdin de grep .

4) fd / 3 pour grep est fermé et non hérité. Ce serait inutilisable de toute façon. grep ne peut filterr que les messages d'erreur de ls

L'exemple fourni dans ABSG n'est probablement pas le plus utile et le commentaire " Close fd 3 pour 'grep' (mais pas 'ls') " est un peu trompeur. Vous pouvez l'interpréter comme suit : " pour les ls, transmettez la valeur de ls.fd / 3 à ls.fd / 1 avant de la désactiver pour qu'elle ne soit pas fermée ".