La plupart des commandes ont un seul canal d’entrée (entrée standard, descripteur de fichier 0) et un seul canal de sortie (sortie standard, descripteur de fichier 1) ou bien agissent sur plusieurs fichiers qu’elles s’ouvrent seules (vous leur transmettez donc un nom de fichier). (Cela vient en plus de l'erreur standard (fd 2), qui filtre généralement jusqu'à l'utilisateur.) Il est cependant parfois pratique de disposer d'une commande qui agit comme un filtre à partir de plusieurs sources ou de plusieurs cibles. Par exemple, voici un script simple qui sépare les lignes impaires d'un fichier de celles paires.
while IFS= read -r line; do
printf '%s\n' "$line"
if IFS= read -r line; then printf '%s\n' "$line" >&3; fi
done >odd.txt 3>even.txt
Supposons maintenant que vous souhaitiez appliquer un filtre différent aux lignes de numéro impair et aux lignes de numéro pair (mais ne les remettez pas ensemble, ce serait un problème différent, non réalisable du shell en général). Dans le shell, vous pouvez uniquement diriger la sortie standard d'une commande vers une autre commande. Pour diriger un autre descripteur de fichier, vous devez d’abord le rediriger vers fd 1.
{ while … done | odd-filter >filtered-odd.txt; } 3>&1 | even-filter >filtered-even.txt
Un autre cas d'utilisation plus simple consiste à filtrer le résultat d'erreur d'une commande .
exec M>&N
redirige un descripteur de fichier vers un autre pour le reste du script (ou jusqu'à ce qu'une autre commande modifie à nouveau les descripteurs de fichier). Certaines fonctionnalités se chevauchent entre exec M>&N
et somecommand M>&N
. La exec
forme est plus puissante en ce sens qu'elle n'a pas besoin d'être imbriquée:
exec 8<&0 9>&1
exec >output12
command1
exec <input23
command2
exec >&9
command3
exec <&8
Autres exemples pouvant présenter un intérêt:
Et pour encore plus d'exemples:
PS C'est une question surprenante de l'auteur de l'article le plus voté sur le site, qui utilise la redirection via fd 3 !
Gilles, arrête de faire le mal
la source
while IFS= read -r line;
? À mon avis, IFS n’a aucun effet ici puisque vous n’attribuez une valeur à une seule variable ( ligne ). Voir cette question.IFS
fait une différence même si vous lisez une variable unique (c'est pour conserver les principaux espaces).sed -ne 'w odd.txt' -e 'n;w even.txt'
?Voici un exemple d'utilisation de FD supplémentaires comme contrôle de conversation en script bash:
la source
Dans le contexte des canaux nommés (fifos), l'utilisation d'un descripteur de fichier supplémentaire peut permettre un comportement de canalisation non bloquant.
Voir: Pipe nommée se fermant prématurément dans le script?
la source
Un descripteur de fichier supplémentaire est utile lorsque vous souhaitez capturer la sortie standard dans une variable tout en souhaitant écrire à l'écran, par exemple dans une interface utilisateur de script bash
la source
Voici un autre scénario où l'utilisation d'un descripteur de fichier supplémentaire semble appropriée (en Bash):
Sécurité du mot de passe de script shell pour les paramètres de ligne de commande
la source
Exemple: utilisation de flock pour forcer les scripts à s'exécuter en série avec des verrous de fichiers
Un exemple consiste à utiliser le verrouillage de fichier pour forcer les scripts à s'exécuter en série sur l'ensemble du système. Ceci est utile si vous ne voulez pas que deux scripts du même type agissent sur les mêmes fichiers. Sinon, les deux scripts pourraient interférer et éventuellement altérer des données.
Utilisez fonctionnellement flock en définissant verrouiller et déverrouiller
Vous pouvez également intégrer cette logique de verrouillage / déverrouillage à des fonctions réutilisables. Le
trap
shell suivant libère automatiquement le verrou de fichier lorsque le script se termine (erreur ou succès).trap
aide à nettoyer vos verrous de fichiers. Le chemin/tmp/file.lock
doit être un chemin codé en dur afin que plusieurs scripts puissent essayer de le verrouiller.La
unlock
logique ci-dessus consiste à supprimer le fichier avant que le verrou ne soit libéré. De cette façon, il nettoie le fichier de verrouillage. Comme le fichier a été supprimé, une autre instance de ce programme peut obtenir le verrou de fichier.Utilisation des fonctions de verrouillage et de déverrouillage dans les scripts
Vous pouvez l'utiliser dans vos scripts comme dans l'exemple suivant.
Si vous voulez que votre code attende jusqu'à ce qu'il soit capable de se verrouiller, vous pouvez ajuster le script comme suit:
la source
À titre d'exemple concret, je viens d'écrire un script qui nécessite les informations de minutage d'une sous-commande. L'utilisation d'un descripteur de fichier supplémentaire m'a permis de capturer le
time
stderr de la commande sans interrompre le stdout ou le stderr de la sous-commande.Cela permet de faire pointer
ls
stderr to fd 3, fd 3 vers stderr du script ettime
stderr vers un fichier. Lorsque le script est exécuté, ses propriétés stdout et stderr sont identiques à celles de la sous-commande, qui peuvent être redirigées normalement. Seuletime
la sortie est redirigée vers le fichier.la source