GNU/Linux >> Znalost Linux >  >> Linux

Kontrola, zda je dir. záznam vrácený readdir je adresář, odkaz nebo soubor. dent->d_type nezobrazuje typ

d_type je optimalizace rychlosti pro úsporu lstat(2) volání, pokud je to podporováno.

Jako readdir (3) manuálová stránka zdůrazňuje, že ne všechny souborové systémy vracejí skutečné informace v d_type pole (obvykle proto, že čtení inodu by vyžadovalo další hledání disku, jako je tomu v případě XFS, pokud jste nepoužili mkfs.xfs -n ftype=1 (předpokládá se -m crc=1 což ještě není výchozí nastavení). Souborové systémy, které vždy nastavují DT_UNKNOWN jsou v reálném životě běžné a nelze je ignorovat. XFS není jediným příkladem.

Vždy potřebujete kód, který se vrátí k použití lstat (2) pokud d_type==DT_UNKNOWN , pokud samotný název souboru nestačí k rozhodnutí, že je nezajímavý. (To je případ některých volajících, například find -name nebo rozšiřující globusy jako *.c , proto readdir nezahrnuje režii jeho vyplňování, pokud by to vyžadovalo další čtení disku.)

Linux getdents(2) manuálová stránka obsahuje ukázkový program, který dělá to, o co se pokoušíte, včetně bloku řetězeného ternárního operátora pro dekódování d_type pole do textových řetězců. (Jak zdůrazňují ostatní odpovědi, vaše chyba je vytisknout jej jako znak, spíše než jej porovnat s DT_REG , DT_DIR , atd.)

Každopádně ostatní odpovědi většinou pokrývaly věci, ale postrádaly kritický detail, že POTŘEBUJETE záložní řešení pro případ, kdy d_type == DT_UNKNOWN (0 v systému Linux. d_type je až do Linuxu 2.6.4 uloženo v tom, co bývalo výplňovým bytem).

Aby byl váš kód přenosný, musí zaškrtnout struct dirent dokonce MÁ d_type pole, pokud jej použijete, jinak se váš kód nebude ani zkompilovat mimo systémy GNU a BSD. (viz readdir(3) )

Napsal jsem příklad hledání adresářů pomocí readdir pomocí d_type s přechodem na stat když d_type není k dispozici v době kompilace, když je DT_UNKNOWN a pro symbolické odkazy.


d_type ve struktuře return udává číslo pro typ. Nemůžete to vytisknout přímo, protože použité hodnoty nelze vytisknout, když jsou interpretovány jako ASCII (například jsou 4 pro adresáře a 8 pro soubory).

Můžete je vytisknout jako čísla takto:

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

Nebo je porovnejte s konstantami jako DT_DIR a vytvořit z toho nějaký smysluplný výstup, jako je typ znaku:

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

Vytiskněte d_type jako celé číslo takto:

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

a uvidíte smysluplné hodnoty.


Linux
  1. Jak najít nejstarší soubor ve stromu adresářů v Linuxu

  2. Když zadáte „ls -a“, jaký je význam „.“ A ".."?

  3. Co se přesně stane, když spustím soubor v prostředí Shell?

  1. jak najít vlastníka souboru nebo adresáře v pythonu

  2. Proveďte příkaz pro každý soubor v aktuálním adresáři

  3. Node.js:Zkontrolujte, zda je soubor symbolickým odkazem při iteraci přes adresář s 'fs'

  1. mkdir -p selže, když adresář existuje

  2. Jak získám absolutní adresář souboru v bash?

  3. bash:./helloworld_s:žádný takový soubor nebo adresář. Soubor tam jasně je