GNU/Linux >> Tutoriels Linux >  >> Linux

Vérifier si un dir. l'entrée renvoyée par readdir est un répertoire, un lien ou un fichier. dent->d_type n'affiche pas le type

d_type est une optimisation de vitesse pour économiser sur lstat(2) appels, lorsqu'ils sont pris en charge.

Comme le readdir (3) la page de manuel indique que tous les systèmes de fichiers ne renvoient pas d'informations réelles dans le d_type champ (généralement parce qu'il faudrait une recherche de disque supplémentaire pour lire l'inode, comme c'est le cas pour XFS si vous n'utilisiez pas mkfs.xfs -n ftype=1 (sous-entendu par -m crc=1 qui n'est pas encore la valeur par défaut). Systèmes de fichiers qui définissent toujours DT_UNKNOWN sont courants dans la vraie vie, et non quelque chose que vous pouvez ignorer. XFS n'est pas le seul exemple.

Vous avez toujours besoin d'un code qui reviendra à l'utilisation de lstat (2) si d_type==DT_UNKNOWN , si le nom du fichier seul ne suffit pas pour décider qu'il n'est pas intéressant. (C'est le cas pour certains appelants, comme find -name ou développer des globs comme *.c , c'est pourquoi readdir n'entraîne pas la surcharge de le remplir si cela prendrait une lecture de disque supplémentaire.)

Le Linux getdents(2) La page de manuel contient un exemple de programme qui fait ce que vous essayez de faire, y compris un bloc chained-terary-operator pour décoder le d_type champ en chaînes de texte. (Comme le soulignent les autres réponses, votre erreur est de l'imprimer en tant que caractère, plutôt que de le comparer à DT_REG , DT_DIR , etc.)

Quoi qu'il en soit, les autres réponses couvraient principalement des choses, mais manquaient le détail critique que vous AVEZ BESOIN d'une alternative pour le cas où d_type == DT_UNKNOWN (0 sous Linux. d_type est stocké dans ce qui était autrefois un octet de remplissage, jusqu'à Linux 2.6.4).

Pour être portable, votre code doit vérifier que struct dirent A même un d_type champ, si vous l'utilisez, ou votre code ne compilera même pas en dehors des systèmes GNU et BSD. (voir readdir(3) )

J'ai écrit un exemple pour trouver des répertoires avec readdir , en utilisant d_type avec un repli sur stat lorsque d_type n'est pas disponible au moment de la compilation, lorsqu'il est DT_UNKNOWN et pour les liens symboliques.


Le d_type dans la structure de retour donne un nombre pour le type. Vous ne pouvez pas l'imprimer directement car les valeurs utilisées ne sont pas imprimables lorsqu'elles sont interprétées en ASCII (par exemple, elles sont 4 pour les répertoires et 8 pour les fichiers.).

Vous pouvez soit les imprimer sous forme de nombres comme ceci :

printf("%d ", dent->d_type)

Ou comparez-les aux constantes comme DT_DIR et construisez une sortie significative à partir de cela, comme un type char :

if(dent->type == DT_DIR) type = 'd'

Imprimer d_type comme un entier comme ceci :

printf("%d ", dent->d_type);

et vous verrez des valeurs significatives.


Linux
  1. Que se passe-t-il exactement lorsque j'exécute un fichier dans le shell ?

  2. Comment Unix garde-t-il une trace du répertoire de travail d'un utilisateur lors de la navigation dans le système de fichiers ?

  3. Comment trouver le type d'un fichier Img et le monter ?

  4. Comprendre le répertoire /etc/sysconfig

  5. Core dumpé, mais le fichier core n'est pas dans le répertoire courant ?

mkdir -p échoue lorsque le répertoire existe

Comment obtenir le répertoire absolu d'un fichier dans bash ?

bash :./helloworld_s :aucun fichier ou répertoire de ce type. Le dossier est clairement là

Que signifie l'astérisque après un nom de fichier lorsque vous tapez `ls -l` ?

Pourquoi le répertoire racine est-il désigné par un signe / ?

Qu'est-ce que le sticky bit dans les systèmes de fichiers UNIX ? Quand est-il utilisé ?