Quelle est la durée de vie d'un descripteur de fichier?

11

Comme décrit ici , les redirections permettent open()d'écrire dans un fichier. Il y a un descripteur de fichier interne (?) Créé dans le shell, puis utilisé en cas de besoin.

Le descripteur interne est-il créé pour toute la durée du script ou la durée de vie du shell? Est-il détruit après un certain temps, un certain nombre d'opérations, etc.?

Je veux dire en particulier les descripteurs de fichiers pour les fichiers que le shell lui-même ouvre pour ses opérations internes. Le descripteur est-il créé et le fichier ouvert pour chaque opération? Combien de temps sont-ils conservés? Exemple:

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

La première instance de descripteur est-elle conservée jusqu'à la deuxième opération?

Qu'en est-il du shell que j'utilise dans un terminal? Je garde parfois une session ouverte pendant des jours, voire des semaines. Conserve-t-il toujours les descripteurs de tous les fichiers sur lesquels j'ai opéré avec des shell intégrés?

Jeff Schaller
la source

Réponses:

4

En bref: un shell fermera presque certainement les descripteurs de fichiers liés aux redirections immédiatement après la fin de la commande.


Détails: Il n'y a aucune mention explicite de la fermeture des fichiers ouverts via des redirections dans POSIX (pour autant que je puisse voir). Mais ne pas les fermer immédiatement ne serait pas très utile.

Les règles de l'environnement dans lesquelles les commandes sont démarrées ne permettent pas de transmettre des descripteurs de fichiers supplémentaires. Le shell devrait prendre soin de fermer tous les fd supplémentaires qu'il a enregistrés lors du démarrage d'une commande qui ne devrait pas les avoir.

Pour les > filenameredirections de sortie habituelles , le fichier aurait besoin d'être tronqué au démarrage de chaque commande, même si le descripteur de fichier était enregistré. Et tout descripteur de fichier enregistré pointerait vers un mauvais fichier si le fichier concerné était renommé ou supprimé entre-temps.

Par exemple, cela ne se comporterait pas correctement si le fd ouvert pour le premier echoétait maintenu ouvert et utilisé tel quel pour le second:

echo foo >> x; mv x y; echo bar >> x

Le modèle fork + exec habituel utilisé pour démarrer des programmes externes facilite également la fermeture automatique des fichiers à la fin de la commande. Le shell n'a besoin que d' fork()ouvrir et d'ouvrir tous les fichiers nécessaires dans le processus enfant avant d'appeler exec()pour remplacer l'enfant par la commande réelle. À la fin du processus enfant, tous les fichiers qu'il ouvre sont automatiquement fermés.


Dansawk , cependant, la syntaxe de la redirection de sortie est similaire au shell, mais tous les fichiers ouverts sont maintenus ouverts jusqu'à la fermeture du script, sauf s'ils sont fermés explicitement. Cela ne s'ouvrira fooqu'une seule fois et ne le tronquera pas non plus entre les impressions:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
ilkkachu
la source
6

Ils sont fermés une fois terminé. Le shell va créer 3 descripteurs de fichiers 0,1,2 pour chaque commande qu'il exécute. Ce ne sont que des chiffres, les chiffres sont réutilisés. Le shell fermera les fichiers avant de réutiliser les descripteurs.

Les descripteurs de fichiers sont également transmis à d'autres processus. Et si vous avez un processus en arrière-plan, il aura toujours des descripteurs de fichiers.

L'exemple utilise 3>&1, cela signifie que le descripteur de fichier 3 fait référence au fichier auquel le descripteur 1 fait actuellement référence.

ctrl-alt-delor
la source