web-dev-qa-db-fra.com

Que sont les descripteurs de fichier, expliqués en termes simples?

  1. Quelle serait une description plus simplifiée des descripteurs de fichiers par rapport à celle de Wikipedia? Pourquoi sont-ils nécessaires? Disons, prenons comme exemple les processus Shell et comment cela s’applique-t-il?

  2. Une table de processus contient-elle plusieurs descripteurs de fichier? Si oui pourquoi?

331
Nishant

En termes simples, lorsque vous ouvrez un fichier, le système d'exploitation crée une entrée pour représenter ce fichier et stocker les informations sur ce fichier ouvert. Donc, si 100 fichiers sont ouverts dans votre système d'exploitation, il y aura 100 entrées dans le système d'exploitation (quelque part dans le noyau). Ces entrées sont représentées par des entiers tels que (... 100, 101, 102 ...). Ce numéro d'entrée est le descripteur de fichier. Il s’agit donc d’un nombre entier représentant uniquement un fichier ouvert dans le système d’exploitation. Si votre processus ouvre 10 fichiers, votre table de processus comportera 10 entrées pour les descripteurs de fichier.

De même, lorsque vous ouvrez une socket réseau, celle-ci est également représentée par un entier et s'appelle Socket Descriptor. J'espère que tu comprends.

494
Tayyab

Un descripteur de fichier est un descripteur opaque utilisé dans l'interface entre l'utilisateur et l'espace noyau pour identifier les ressources de fichier/socket. Par conséquent, lorsque vous utilisez open() ou socket() (appels système pour l'interface avec le noyau), un descripteur de fichier, qui est un entier (il s'agit en fait d'un index dans la structure du processus), vous est attribué. ce n'est pas important). Par conséquent, si vous souhaitez vous connecter directement au noyau en utilisant les appels système à read(), write(), close() etc., le descripteur que vous utilisez est un descripteur de fichier.

Il existe une couche d'abstraction superposée sur les appels système, qui est l'interface stdio. Cela fournit plus de fonctionnalités/fonctionnalités que les appels système de base. Pour cette interface, le descripteur opaque que vous obtenez est un FILE*, qui est renvoyé par l'appel fopen(). Il existe de nombreuses fonctions qui utilisent l'interface stdiofprintf(), fscanf(), fclose(), qui sont là pour vous simplifier la vie. En C, stdin, stdout et stderr sont FILE*, qui sous UNIX correspondent respectivement aux descripteurs de fichier 0, 1 et 2.

99
Beano

Écoutez-le dans la bouche du cheval: APUE (Richard Stevens).
Pour le noyau, tous les fichiers ouverts sont référencés par des descripteurs de fichiers. Un descripteur de fichier est un nombre non négatif.

Lorsque nous ouvrons un fichier existant ou créons un nouveau fichier, le noyau renvoie un descripteur de fichier au processus. Le noyau conserve une table de tous les descripteurs de fichiers ouverts. , qui sont en cours d'utilisation. L'attribution de descripteurs de fichier est généralement séquentielle et ils sont attribués au fichier en tant que prochain descripteur de fichier libre à partir du pool de descripteurs de fichiers libres. Lorsque nous fermons le fichier, le descripteur de fichier est libéré et est disponible pour une affectation ultérieure.
Voir cette image pour plus de détails:

Two Process

Lorsque nous voulons lire ou écrire un fichier, nous identifions le fichier avec le descripteur de fichier renvoyé par open () ou create () et utilisez-le comme argument pour read () ou write () .
C’est par convention que, les shells du système UNIX associent le descripteur de fichier 0 à une entrée standard d’un processus, le descripteur de fichier 1 à Sortie standard et descripteur de fichier 2 avec Erreur standard .
Le descripteur de fichier est compris entre 0 et OPEN_MAX. La valeur maximale du descripteur de fichier peut être obtenue avec ulimit -n. Pour plus d'informations, consultez le 3ème chapitre du livre APUE.

90
Shekhar Kumar

Plus de points concernant File Descriptor:

  1. File Descriptors (FD) sont des entiers non négatifs (0, 1, 2, ...) qui sont associés aux fichiers ouverts.

  2. 0, 1, 2 sont standard FD qui correspond à STDIN_FILENO, STDOUT_FILENO et STDERR_FILENO (défini dans unistd.h) ouvert par défaut pour le compte de Shell au démarrage du programme.

  3. Les FD sont alloués dans l'ordre séquentiel, c'est-à-dire la valeur entière non allouée la plus basse possible.

  4. Les FD pour un processus particulier sont visibles dans /proc/$pid/fd (sur les systèmes Unix).

17
Sandeep_black

En plus d'autres réponses, Unix considère tout comme un système de fichiers. Votre clavier est un fichier qui est lu uniquement du point de vue du noyau. L'écran est un fichier en écriture seule. De même, les dossiers, les périphériques d’entrée-sortie, etc. sont également considérés comme des fichiers. Chaque fois qu'un fichier est ouvert, par exemple, lorsque les pilotes de périphérique [pour les fichiers de périphérique] demandent un open (), ou qu'un processus ouvre un fichier utilisateur, le noyau alloue un descripteur de fichier, un entier spécifiant l'accès à ce fichier, en lecture seule. , écrivez seulement, etc. [pour référence: https://en.wikipedia.org/wiki/Everything_is_a_file ]

14
Balu

D'autres réponses ont ajouté des trucs géniaux. Je vais ajouter seulement mes 2 cents.

Selon Wikipedia, nous savons avec certitude: un descripteur de fichier est un entier non négatif. La chose la plus importante qui me manque est de dire:

Les descripteurs de fichier sont liés à un ID de processus.

Nous savons que les descripteurs de fichiers les plus connus sont 0, 1 et 2. 0 correspond à STDIN, 1 à STDOUT et 2 à STDERR.

Disons, prenons l'exemple des processus Shell et comment cela s'applique-t-il?

Découvrez ce code

#>sleep 1000 &
[12] 14726

Nous avons créé un processus avec l'ID 14726 (PID). En utilisant le lsof -p 14726, nous pouvons obtenir les choses comme ceci:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

La quatrième colonne FD et la colonne très suivante TYPE correspondent au descripteur de fichier et au type de descripteur de fichier.

Certaines des valeurs pour le FD peuvent être:

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

Mais le descripteur de fichier réel est sous:

NUMBER – Represent the actual file descriptor. 

Le caractère après le nombre, à savoir "1u", représente le mode dans lequel le fichier est ouvert. r pour lire, w pour écrire, u pour lire et écrire.

TYPE spécifie le type du fichier. Certaines des valeurs de TYPE sont:

REG – Regular File
DIR – Directory
FIFO – First In First Out

Mais tous les descripteurs de fichiers sont CHR - Fichier spécial de caractères (ou fichier de périphérique de caractères)

Maintenant, nous pouvons identifier les descripteurs de fichier pour STDIN, STDOUT et STDERR facile avec lsof -p PID, ou nous pouvons voir la même chose si nous ls /proc/PID/fd.

Notez également que la table de descripteur de fichier dont le noyau assure le suivi n’est pas la même que la table de fichiers ou la table inodes. Celles-ci sont séparées, comme l'expliquent d'autres réponses.

fd table

Vous pouvez vous demander où sont physiquement ces descripteurs de fichier et ce qui est stocké dans /dev/pts/6 par exemple

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Eh bien, /dev/pts/6 ne vit que dans la mémoire. Ce ne sont pas des fichiers normaux, mais des fichiers de périphérique de caractères . Vous pouvez vérifier cela avec: ls -l /dev/pts/6 et ils commenceront par c, dans mon cas crw--w----.

Pour rappel, la plupart des systèmes d’exploitation Linux, comme les systèmes d’exploitation, définissent sept types de fichiers:

  • Dossiers réguliers
  • Répertoires
  • Fichiers de périphérique de personnage
  • Bloquer les fichiers de l'appareil
  • Sockets de domaine local
  • Tubes nommés (FIFO) et
  • Liens symboliques
13
prosti

Descripteurs de fichier (FD):

  • Dans Linux/Unix, tout est un fichier. Les fichiers normaux, les répertoires et même les périphériques sont des fichiers. Chaque fichier a un numéro associé appelé descripteur de fichier (FD).
  • Votre écran comporte également un descripteur de fichier. Lorsqu'un programme est exécuté, la sortie est envoyée au descripteur de fichier de l'écran et vous voyez la sortie du programme sur votre moniteur. Si la sortie est envoyée au descripteur de fichier de l'imprimante, la sortie du programme aurait été imprimée.

    Redirection d'erreur:
    Chaque fois que vous exécutez un programme/une commande sur le terminal, 3 fichiers sont toujours ouverts
    1. entrée standard
    2. sortie standard
    3. erreur standard.

    Ces fichiers sont toujours présents chaque fois qu'un programme est exécuté. Comme expliqué précédemment, un descripteur de fichier est associé à chacun de ces fichiers.
    FichierDescripteur de fichier
    Entrée standard STDIN 0
    Sortie standard STDOUT 1
    Erreur type STDERR 2

  • Par exemple, lors de la recherche de fichiers, on obtient généralement des erreurs d'autorisation refusée ou un autre type d'erreur. Ces erreurs peuvent être enregistrées dans un fichier particulier.
    Exemple 1

$ ls mydir 2> errorsfile.txt

Le descripteur de fichier pour l'erreur type est 2.
S'il n'y a pas de répertoire nommé mydir, la sortie de la commande sera sauvegardée dans le fichier errorfile.txt
En utilisant "2>", nous redirigeons la sortie d'erreur vers un fichier nommé "errorfile.txt"
Ainsi, la sortie du programme n'est pas encombrée d'erreurs.

J'espère que vous avez eu votre réponse.

5
Abhishek Kamal

Descripteurs de fichier

  • Pour le noyau, tous les fichiers ouverts sont référencés par des descripteurs de fichiers.
  • Un descripteur de fichier est un entier non négatif.
  • Lorsque nous ouvrons un fichier existant ou créons un nouveau fichier, le noyau renvoie un descripteur de fichier à un processus.
  • Lorsque nous voulons lire ou écrire sur un fichier, nous identifions le fichier avec le descripteur de fichier qui a été réaccordé par open ou create, en tant qu'argument à lire ou à écrire.
  • Chaque processus UNIX a 20 descripteurs de fichier et est éliminé, numérotés de 0 à 19, mais il a été étendu à 63 par de nombreux systèmes.
  • Les trois premiers sont déjà ouverts lorsque le processus commence 0: l'entrée standard 1: la sortie standard 2: la sortie d'erreur standard
  • Lorsque le processus parent divise un processus, le processus enfant hérite des descripteurs de fichier du processus parent.
3
Mahendra suthar

Tous les systèmes d'exploitation ont des processus (p) en cours d'exécution, par exemple p1, p2, p3 , etc. Chaque processus utilise généralement des fichiers en continu.

Chaque processus est constitué d'un arbre de processus (ou d'une table de processus, dans un autre phrasé).

Habituellement, les systèmes d'exploitation représentent chaque fichier de chaque processus par un nombre (c'est-à-dire, dans chaque arborescence/table de processus).

Le premier fichier utilisé dans le processus est fichier0 , le second est fichier1 , le troisième est fichier2 , etc.

n tel numéro est un descripteur de fichier.

Les descripteurs de fichier sont généralement des entiers (0, 1, 2 et non 0.5, 1.5, 2.5).

Étant donné que nous décrivons souvent les processus comme des "tables de processus", et étant donné que les tables ont des lignes (entrées), nous pouvons dire que la cellule de descripteur de fichier de chaque entrée utilise pour représenter l’entrée entière.

De la même manière, lorsque vous ouvrez une socket réseau, celle-ci comporte un descripteur de socket.

Dans certains systèmes d'exploitation, vous pouvez manquer de descripteurs de fichiers, mais ce cas est extrêmement rare et l'utilisateur moyen ne devrait pas s'en inquiéter.

Les descripteurs de fichier peuvent être globaux (le processus A commence par exemple par 0, et finit par tel par 1; le processus B par deux, et finit par par 3), etc., mais autant que je sache, généralement dans les systèmes d'exploitation modernes, fichier les descripteurs ne sont pas globaux, et sont en fait spécifiques à un processus (le processus A commence par, par exemple, 0 et se termine par, par 5, alors que le processus B commence par 0 et se termine par, par 10).

3
JohnDoea

Ajout à des réponses surtout simplifiées.
Si vous travaillez avec des fichiers dans un script bash, il est préférable d’utiliser un descripteur de fichier.
Par exemple:-
Vous voulez lire et écrire à partir du fichier "test.txt".
Utilisez le descripteur de fichier comme indiqué ci-dessous

FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor
1
sumitsinghdeode