GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Prüfen, ob ein dir. Der von readdir zurückgegebene Eintrag ist ein Verzeichnis, ein Link oder eine Datei. dent->d_type zeigt den Typ nicht an

d_type ist eine Geschwindigkeitsoptimierung, um auf lstat(2) zu sparen Anrufe, wenn es unterstützt wird.

Als readdir (3) Manpage weist darauf hin, dass nicht alle Dateisysteme echte Informationen in d_type zurückgeben Feld (normalerweise, weil es eine zusätzliche Festplattensuche erfordern würde, um den Inode zu lesen, wie es bei XFS der Fall ist, wenn Sie mkfs.xfs -n ftype=1 nicht verwenden (impliziert durch -m crc=1 was noch nicht der Standard ist). Dateisysteme, die immer DT_UNKNOWN setzen sind im wirklichen Leben üblich und können nicht ignoriert werden. XFS ist nicht das einzige Beispiel.

Sie benötigen immer Code, der auf die Verwendung von lstat zurückgreift (2) wenn d_type==DT_UNKNOWN , wenn der Dateiname allein nicht ausreicht, um zu entscheiden, ob er uninteressant ist. (Dies ist bei einigen Anrufern der Fall, wie z. B. find -name oder expandierende Globs wie *.c , weshalb readdir verursacht nicht den Aufwand, es auszufüllen, wenn es einen zusätzlichen Lesevorgang auf der Festplatte erfordern würde.)

Der Linux-getdents(2) Manpage enthält ein Beispielprogramm, das das tut, was Sie versuchen, einschließlich eines verketteten ternären Operatorblocks zum Decodieren von d_type Feld in Textzeichenfolgen. (Wie die anderen Antworten zeigen, druckt Ihr Fehler es als Zeichen aus, anstatt es mit DT_REG zu vergleichen , DT_DIR usw.)

Wie auch immer, die anderen Antworten deckten hauptsächlich Dinge ab, übersahen jedoch das kritische Detail, dass Sie ein Fallback BENÖTIGEN für den Fall d_type == DT_UNKNOWN (0 unter Linux. d_type wird in einem ehemaligen Füllbyte gespeichert, bis Linux 2.6.4).

Um portierbar zu sein, muss Ihr Code diesen struct dirent überprüfen HAT sogar einen d_type Feld, wenn Sie es verwenden, oder Ihr Code wird nicht einmal kompiliert außerhalb von GNU- und BSD-Systemen. (siehe readdir(3) )

Ich habe ein Beispiel für das Finden von Verzeichnissen mit readdir geschrieben , mit d_type mit einem Fallback auf stat wenn d_type zur Kompilierzeit nicht verfügbar ist, wenn es DT_UNKNOWN ist und für symbolische Links.


Die d_type in der Rückgabestruktur gibt eine Zahl für den Typ an. Sie können das nicht direkt drucken, da die verwendeten Werte nicht druckbar sind, wenn sie als ASCII interpretiert werden (zum Beispiel sind sie 4 für Verzeichnisse und 8 für Dateien.).

Sie können sie entweder als Zahlen wie folgt drucken:

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

Oder vergleichen Sie sie mit den Konstanten wie DT_DIR und konstruieren Sie daraus eine aussagekräftige Ausgabe, wie einen char-Typ:

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

Drucken Sie d_type als Integer wie folgt:

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

und Sie sehen aussagekräftige Werte.


Linux
  1. So finden Sie die älteste Datei in einem Verzeichnisbaum in Linux

  2. Was genau passiert, wenn ich eine Datei in der Shell ausführe?

  3. Wie verfolgt Unix das Arbeitsverzeichnis eines Benutzers beim Navigieren im Dateisystem?

  4. Wie finde ich den Typ einer Img-Datei und mounte sie?

  5. Core-Dump, aber Core-Datei befindet sich nicht im aktuellen Verzeichnis?

Wenn Sie „ls -a“ eingeben, was ist die Bedeutung von „.“ Und ".."?

Verstehen des Verzeichnisses /etc/sysconfig

Wie finde ich den Besitzer einer Datei oder eines Verzeichnisses in Python?

Keine Manpage für den cd-Befehl

Warum wird das Root-Verzeichnis durch ein /-Zeichen gekennzeichnet?

Was ist das Sticky Bit in UNIX-Dateisystemen? Wann wird es verwendet?