3

我正在尝试在 Linux 中检查一个文件夹是否有任何子文件夹而不遍历其子文件夹。到目前为止,我发现的最接近的是使用ftw并在第一个子文件夹处停止 - 或使用scandir并过滤结果。然而,对于我的目的来说,两者都是矫枉过正,我只是想要一个是/否。

在 Windows 上,这是通过调用SHGetFileInfo然后dwAttributes & SFGAO_HASSUBFOLDER对返回的结构进行测试来完成的。Linux上有这样的选项吗?

4

3 回答 3

4

标准答案是在目录上调用stat,然后检查 st_nlink 字段(“硬链接数”)。在标准文件系统上,每个目录都保证有 2 个硬链接(.以及从父目录到当前目录的链接),因此每个超过 2 个的硬链接都表示一个子目录(具体来说,是子目录..到当前目录的链接)。

但是,据我了解,文件系统不需要实现此功能(例如,请参阅此邮件列表发布),因此不能保证它可以正常工作。

否则,您必须照常做:

  1. 使用带有 GNU 特定标志的glob或scandirreaddir迭代目录的内容。GLOB_ONLYDIR
  2. 对每个结果调用stat并检查S_ISDIR(s.st_mode)以确认找到的文件是目录。或者,不可移植地,检查struct dirent.d_type: 如果是,DT_DIR那么它是一个文件,如果是DT_UNKNOWN,你将不得不统计它。
于 2010-04-05T18:12:17.023 回答
2

您提到的可能性(以及 e.James 的)在我看来似乎比 C++ 程序更适合 shell 脚本。假设“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;
}
于 2010-04-05T18:19:43.887 回答
0

getdirentries是否确实希望您这样做?我认为如果没有目录,它应该什么都不返回。我自己会尝试过,但暂时无法访问 linux 机器:(

于 2010-04-05T18:02:05.263 回答