Проверка, если подпапки существуют Linux
Вопрос
Я пытаюсь проверить, есть ли папка любые подпапки без итерации через своих детей, в Linux. Ближайший, который я нашел до сих пор, использует ftw
и останавливаясь на первой подпапке - или используя scandir
и фильтрация через результаты. Оба, однако, являются излишним для моих целей, я просто хочу да / нет.
В окнах это делается по телефону SHGetFileInfo
а затем тестирование dwAttributes & SFGAO_HASSUBFOLDER
на возвращенной структуре. Есть ли такой вариант на Linux?
Решение
Стандартный ответ - звонить статистика В каталоге, затем проверьте поле ST_NLINK («Количество жестких ссылок»). На стандартной файловой системе каждый каталог гарантированно имеет 2 жестких ссылки (.
и ссылка из родительского каталога к текущему каталогу), поэтому каждая жесткая связь за пределы 2 указывает подкаталог (конкретно, подкаталог ..
Ссылка на текущий каталог).
Тем не менее, мое понимание того, что файловые системы не требуются для реализации этого (см., Например, Этот рассылки по публикации), так что это не гарантированно работать.
В противном случае вы должны делать, как вы делаете:
- Итерация по содержанию каталога с использованием Глобай с конкретным GNU
GLOB_ONLYDIR
Флаг, или скандировать, или readdir.. - Вызов статистика на каждом результате и проверьте
S_ISDIR(s.st_mode)
Чтобы убедиться, что найденные файлы - это каталоги. Или, неоттечно, проверьтеstruct dirent.d_type
: если этоDT_DIR
тогда это файл, и если этоDT_UNKNOWN
, Вам придется ставить это в конце концов.
Другие советы
Возможности, которые вы упомянули (а также E.james's), кажется, мне лучше подходят для скрипта оболочки, чем программа C ++. Предполагая, что тег «C ++» был преднамеренным, я думаю, что вы, вероятно, будете лучше использовать POSIX API напрямую:
// 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;
}
Делает GetDireNtries. Хотите, чтобы вы хотели это сделать? Я думаю, что это не дозвонит ничего, если нет каталогов. Я бы пробовал это сам, но временно без доступа к коробке Linux :(