GNU/Linux >> Tutoriels Linux >  >> Linux

Descripteurs de fichiers et scripts shell ?

J'ai beaucoup de mal à comprendre comment utiliser les descripteurs de fichiers dans les scripts shell.

Je connais les bases telles que

exec 5 > /tmp/foo

Donc fd 5 est attaché à foo pour l'écriture.

exec 6 < /tmp/bar

… pour la lecture.

exec 5>&-

… fermer fd.

Maintenant, qu'est-ce que cela fait ?

#!/bin/bash

exec 5 > /tmp/foo 
exec 6 < /tmp/bar 

cat <&6 | while read a
do
     echo $a >&5
done

Si je comprends bien &5 ferme le fd, alors comment la sortie est-elle toujours redirigée avec succès après chaque appel ?

Ceci est une copie des pâtes de :Ici

Il prétend l'utiliser sur un simple fichier echo $a > file rendrait cela beaucoup plus rapide, mais je ne comprends pas. J'apprécierais tous les liens vers un tutoriel décent. J'ai l'impression que les pouvoirs de Google me font défaut.

Réponse acceptée :

Tout d'abord, notez que la syntaxe de fermeture est 5>&- ou 6<&- , selon que le descripteur de fichier est lu en écriture ou en lecture. Il semble y avoir une faute de frappe ou un problème de formatage dans cet article de blog.

Voici le script commenté.

exec 5>/tmp/foo       # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar       # open /tmp/bar for reading, on fd 6
cat <&6 |             # call cat, with its standard input connected to
                      # what is currently fd 6, i.e., /tmp/bar
while read a; do      # 
  echo $a >&5         # write to fd 5, i.e., /tmp/foo
done                  # 

Il n'y a pas de fermeture ici. Étant donné que toutes les entrées et sorties vont au même endroit dans cet exemple simple, l'utilisation de descripteurs de fichiers supplémentaires n'est pas nécessaire. Vous pourriez écrire

cat </tmp/bar |
while read a; do
  echo $a
done >/tmp/foo

L'utilisation de descripteurs de fichiers explicites devient utile lorsque vous souhaitez écrire dans plusieurs fichiers à tour de rôle. Par exemple, considérez un script qui génère des données dans un fichier de sortie de données et enregistre les données dans un fichier journal et éventuellement des messages d'erreur également. Cela signifie trois canaux de sortie :un pour les données, un pour les journaux et un pour les erreurs. Puisqu'il n'y a que deux descripteurs standard pour la sortie, un troisième est nécessaire. Vous pouvez appeler exec pour ouvrir les fichiers de sortie :

exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&-  # close the data output file
echo "output file closed" >&3

La remarque sur l'efficacité intervient lorsque vous avez une redirection dans une boucle, comme celle-ci (en supposant que le fichier est vide pour commencer) :

while …; do echo $a >>/tmp/bar; done

A chaque itération, le programme ouvre /tmp/bar , recherche la fin du fichier, ajoute des données et ferme le fichier. Il est plus efficace d'ouvrir le fichier une fois pour toutes :

while …; do echo $a; done >/tmp/bar

Lorsqu'il y a plusieurs redirections à des moments différents, appeler exec effectuer des redirections plutôt que d'envelopper un bloc dans une redirection devient utile.

exec >/tmp/bar
while …; do echo $a; done

Vous trouverez plusieurs autres exemples de redirection en parcourant le io-redirection tag sur ce site.

Connexe :Personnalisation du shell bash :Gras/coloration de la commande ?
Linux
  1. Comment créer un fichier temporaire en script shell ?

  2. Mécanisme des blocs d'instructions dans les scripts Shell ?

  3. Que fait Exec 3 ?

  4. Dois-je utiliser Apt ou Apt-get dans les scripts Shell ?

  5. Threads et descripteurs de fichiers

Script Bash - Instructions conditionnelles

Script bash (III)

Qu'est-ce que Shebang dans Linux Shell Scripting ?

Shell Scripting Part4 - Entrée, sortie et redirection

Tutoriel étape par étape sur les scripts shell

Qu'est-ce qu'un fichier .sh ?