التحقق مما إذا كانت المجلدات الفرعية موجودة Linux

StackOverflow https://stackoverflow.com/questions/2579948

  •  24-09-2019
  •  | 
  •  

سؤال

أحاول التحقق مما إذا كان لدى المجلد أي مجلدات دون التكرار من خلال أطفاله ، في Linux. الأقرب الذي وجدته حتى الآن يستخدم ftw والتوقف في المجلد الفرعي الأول - أو باستخدام scandir والتصفية من خلال النتائج. كلاهما ، مع ذلك ، مبالغة لأغاني ، أريد ببساطة نعم/لا.

على Windows ، يتم ذلك عن طريق الاتصال SHGetFileInfo ثم الاختبار dwAttributes & SFGAO_HASSUBFOLDER على الهيكل الذي تم إرجاعه. هل هناك مثل هذا الخيار على Linux؟

هل كانت مفيدة؟

المحلول

الجواب القياسي هو الاتصال Stat في الدليل ، ثم تحقق من حقل ST_NLINK ("عدد الروابط الصلبة"). على نظام الملفات القياسي ، يضمن كل دليل أن يكون له رابطان صلبان (. ويشير الرابط من الدليل الأم إلى الدليل الحالي) ، لذلك يشير كل رابط صلب يتجاوز 2 إلى دليل فرعي (على وجه التحديد ، الدليل الفرعي .. رابط إلى الدليل الحالي).

ومع ذلك ، أفهم أن أنظمة الملفات ليست مطلوبة لتنفيذ هذا (انظر ، على سبيل المثال ، نشر القائمة البريدية هذه) ، لذلك ليس مضمون العمل.

خلاف ذلك ، عليك أن تفعل كما تفعل:

  1. تكرار على محتويات الدليل باستخدام العالم مع GNU محددة GLOB_ONLYDIR العلم ، أو الفراغ, ، أو Readdir.
  2. مكالمة Stat في كل نتيجة وتحقق S_ISDIR(s.st_mode) للتحقق من أن الملفات الموجودة هي الدلائل. أو ، بشكل غير محدد ، تحقق struct dirent.d_type: إذا كان الأمر كذلك DT_DIR ثم إنه ملف ، وإذا كان كذلك DT_UNKNOWN, ، سيكون عليك أن تقتصرها بعد كل شيء.

نصائح أخرى

يبدو لي الإمكانيات التي ذكرتها (وكذلك E.James) وكأنها أكثر ملاءمة لنص shell من برنامج C ++. على افتراض أن علامة "C ++" كانت متعمدة ، أعتقد أنك ربما تكون أفضل حالًا باستخدام واجهة برمجة تطبيقات POSIX مباشرة:

// 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 :(

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top