Pregunta

Estoy tratando de verificar si una carpeta tiene subcarpetas sin iterar a través de sus hijos, en Linux. Lo más cercano que he encontrado hasta ahora está usando ftw y detenerse en la primera subcarpeta, o usar scandir y filtrarse a través de los resultados. Sin embargo, ambos son una exageración para mis propósitos, simplemente quiero un sí/no.

En Windows, esto se hace llamando SHGetFileInfo y luego probando dwAttributes & SFGAO_HASSUBFOLDER en la estructura devuelta. ¿Hay tal opción en Linux?

¿Fue útil?

Solución

La respuesta estándar es llamar estadística En el directorio, luego verifique el campo ST_NLINK ("Número de enlaces duros"). En un sistema de archivos estándar, se garantiza que cada directorio tenga 2 enlaces duros (. y el enlace del directorio principal al directorio actual), por lo que cada enlace duro más allá de 2 indica un subdirectorio (específicamente, el subdirectorio .. enlace al directorio actual).

Sin embargo, tengo entendido que los sistemas de archivos no son necesarios para implementar esto (ver, por ejemplo, Esta publicación de lista de correo), por lo que no se garantiza que funcione.

De lo contrario, tienes que hacer lo que estás haciendo:

  1. Iterar sobre el contenido del directorio utilizando parar con la GNU específica GLOB_ONLYDIR bandera, o escandir, o readdir.
  2. Llamar estadística en cada resultado y verificar S_ISDIR(s.st_mode) Para verificar que los archivos se encuentran son directorios. O, de manera inalcanzable, verifique struct dirent.d_type: si es DT_DIR Entonces es un archivo, y si es DT_UNKNOWN, tendrás que estadificarlo después de todo.

Otros consejos

Las posibilidades que ha mencionado (así como las de E.James) me parecen ser más adecuadas para un script de shell que un programa C ++. Suponiendo que la etiqueta "C ++" fue intencional, creo que probablemente estarías mejor usando la API POSIX directamente:

// 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;
}

Lo hace getdirentries ¿Quieres que quieras que haga? Creo que no devuelve nada si no hay directorios. Hubiera probado esto yo mismo, pero estoy temporalmente sin acceso a una caja de Linux :(

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top