Verificação se os subpastas existirem Linux
Pergunta
Estou tentando verificar se uma pasta possui subpastas sem itetar seus filhos, no Linux. O mais próximo que encontrei até agora está usando ftw
e parando na primeira subpasta - ou usando scandir
e filtrando os resultados. Ambos são, no entanto, um exagero para meus propósitos, eu simplesmente quero um sim/não.
No Windows, isso é feito ligando SHGetFileInfo
e depois testando dwAttributes & SFGAO_HASSUBFOLDER
na estrutura retornada. Existe essa opção no Linux?
Solução
A resposta padrão é ligar Estado No diretório, verifique o campo st_nlink ("Número de links rígidos"). Em um sistema de arquivos padrão, cada diretório tem a garantia de ter 2 links rígidos (.
e o link do diretório pai para o diretório atual), então cada link rígido além de 2 indica um subdiretório (especificamente, o subdiretório's ..
link para o diretório atual).
No entanto, entendi que os sistemas de arquivos não são obrigados a implementar isso (ver, por exemplo, Esta postagem da lista de discussão), portanto, não é garantido trabalhar.
Caso contrário, você precisa fazer o que estiver fazendo:
- Itera sobre o conteúdo do diretório usando glob com o GNU específico
GLOB_ONLYDIR
bandeira, ou Scandir, ou readdir. - Ligar Estado em cada resultado e verifique
S_ISDIR(s.st_mode)
Para verificar se os arquivos encontrados são diretórios. Ou, de maneira não por favor, verifiquestruct dirent.d_type
: se éDT_DIR
então é um arquivo e se forDT_UNKNOWN
, você terá que estatá -lo, afinal.
Outras dicas
As possibilidades que você mencionou (assim como as de E.James) me parecem que elas são mais adequadas para um script de shell do que um programa C ++. Presumindo que a tag "C ++" fosse intencional, acho que você provavelmente estaria melhor usando a API POSIX diretamente:
// 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;
}
Faz getDirentries Quer que você queira fazer? Eu acho que não devolver nada se não houver diretórios. Eu teria tentado isso sozinho, mas estou temporariamente sem acesso a uma caixa Linux :(