Verifica se le sottocartelle esistono Linux
Domanda
Sto cercando di verificare se una cartella ha delle sottocartelle senza ripetere i suoi figli, in Linux. Il più vicino che ho trovato finora è usare ftw
e fermandosi alla prima sottocartella o usando scandir
e filtrando attraverso i risultati. Entrambi, sono, tuttavia, un eccesso per i miei scopi, voglio semplicemente un sì/no.
Su Windows, questo viene fatto chiamando SHGetFileInfo
e poi test dwAttributes & SFGAO_HASSUBFOLDER
sulla struttura restituita. Esiste una tale opzione su Linux?
Soluzione
La risposta standard è chiamare statistica Nella directory, quindi controllare il campo ST_NLINK ("Numero di collegamenti duri"). Su un filesystem standard, ogni directory è garantita per avere 2 collegamenti rigidi (.
e il collegamento dalla directory genitore alla directory corrente), quindi ogni collegamento duro oltre 2 indica una sottodirectory (in particolare, la sottodirectory ..
collegamento alla directory corrente).
Tuttavia, mi capisce che i filesystem non sono tenuti a implementarlo (vedi, ad esempio, Questo post della mailing list), quindi non è garantito funzionare.
Altrimenti, devi fare come stai facendo:
- Iterare sul contenuto della directory usando glob con il GNU specifico
GLOB_ONLYDIR
bandiera, o Scandir, o readdir. - Chiamata statistica su ogni risultato e controlla
S_ISDIR(s.st_mode)
Per verificare che i file trovati siano directory. O, non importabilmente, controllastruct dirent.d_type
: se èDT_DIR
allora è un file e se lo èDT_UNKNOWN
, dovrai statlo dopo tutto.
Altri suggerimenti
Le possibilità che hai menzionato (così come di E.James) mi sembrano come se fossero più adatti a uno script di shell rispetto a un programma C ++. Presumendo che il tag "C ++" fosse intenzionale, penso che probabilmente starai meglio usando l'API POSIX direttamente:
// warning: untested code.
bool has_subdir(char const *dir) {
std::string dot("."), dotdot("..");
bool found_subdir = false;
DIR *directory;
if (NULL == (directory = opendir(dir)))
return false;
struct dirent *entry;
while (!found_subdir && ((entry = readdir(directory)) != NULL)) {
if (entry->d_name != dot && entry->d_name != dotdot) {
struct stat status;
stat(entry->d_name, &status);
found_subdir = S_ISDIR(status.st_mode);
}
}
closedir(directory);
return found_subdir;
}
Fa getDirentries Vuoi che tu voglia che faccia? Penso che shoudl non restituisca nulla se non ci sono directory. Avrei provato questo da solo, ma sono temporaneamente senza accesso a una scatola Linux :(