מטפלי קובץ קבצים ספריות

rmdir#

מסיר ספרייה ריקה.

rmdir מבקש ממערכת ההפעלה למחוק את הספרייה שנקרא בשם FILENAME. הספרייה חייבת להיות ריקה - היא חייבת להכיל רשומות שאינן . ו־... אם FILENAME מושמט, rmdir פועל על $_. זוהי עטיפה דקה מעל קריאת המערכת rmdir(2) ונושאת את כל ההגבלות שלה: אינך יכול להסיר ספרייה לא־ריקה, אינך יכול להסיר ספרייה שאין לך הרשאת כתיבה על ההורה שלה, וברוב המערכות אינך יכול להסיר את ספריית העבודה הנוכחית שלך.

תקציר#

rmdir FILENAME
rmdir

מה מקבלים בחזרה#

1 בהצלחה, 0 בכישלון (כש־$! מוגדר ל־errno מקריאת המערכת שנכשלה). בניגוד לרוב פרימיטיבי ה־I/O, rmdir אינו מחזיר undef בכישלון - הוא מחזיר את המספר השלם 0, כך שהבדיקה הנפוצה rmdir $dir or die $! עדיין עובדת כי 0 הוא שקר.

תמיד בדוק את ערך ההחזרה. rmdir כושל הוא אחרת שקט; השורה הבאה בקוד תמשיך בשמחה כאילו הספרייה הוסרה.

rmdir $dir
    or die "rmdir $dir failed: $!";

מצב גלובלי שהוא נוגע בו#

  • $_ - בשימוש כ־FILENAME כאשר לא ניתן ארגומנט.

  • $! - מוגדר ל־errno של קריאת rmdir(2) שנכשלה בכישלון; נשאר ללא שינוי בהצלחה. קרא אותו מיד; כל קריאת מערכת מתערבת עשויה לדרוס אותו.

דוגמאות#

קריאה רגילה, ספרייה מפורשת:

rmdir "build/tmp"
    or die "rmdir build/tmp: $!";

יעד ברירת מחדל. בתוך while (readdir ...) או לולאה שמשאירה את השם ב־$_:

for (@empty_dirs) {
    rmdir or warn "rmdir $_: $!";
}

הבחנה בין ״כבר נעלם״ לבין שגיאה אמיתית. ENOENT משמעו שהספרייה אינה קיימת, וזה לעתים קרובות בסדר עבור קוד ניקוי:

use Errno qw(ENOENT);
unless (rmdir $dir) {
    die "rmdir $dir: $!" unless $! == ENOENT;
}

הסרת ספרייה רק לאחר ריקונה תחילה:

opendir my $dh, $dir or die "opendir $dir: $!";
while (my $entry = readdir $dh) {
    next if $entry eq '.' or $entry eq '..';
    unlink "$dir/$entry" or die "unlink $dir/$entry: $!";
}
closedir $dh;
rmdir $dir or die "rmdir $dir: $!";

הסרה רקורסיבית אינה העבודה של rmdir. השתמש ב־remove_tree של File::Path - הוא עובר על העץ ומוחק רשומות מלמטה למעלה:

use File::Path qw(remove_tree);
remove_tree("build", { error => \my $err });
die "remove_tree: @$err" if @$err;

מקרי קצה#

  • ספרייה אינה ריקה: $! מוגדר ל־ENOTEMPTY ברוב מערכות Unix (חלק מ־BSDים משתמשים ב־EEXIST). זהו כישלון rmdir הנפוץ ביותר. רשום את תוכן הספרייה או קרא ל־remove_tree אם מחיקה רקורסיבית היא מה שאתה באמת רוצה.

  • ללא ארגומנט: rmdir ללא ארגומנט משתמש ב־$_, לא ב־@ARGV ולא בספרייה הנוכחית. כתיבת rmdir() עם סוגריים ריקים זהה ל־rmdir ללא ארגומנט - הוא עדיין קורא את $_.

  • symlink לספרייה: rmdir מסרב להסיר symlinks; הוא פועל על ספריות בלבד. השתמש ב־unlink על ה־symlink עצמו. $! מוגדר בדרך כלל ל־ENOTDIR.

  • ספריית עבודה נוכחית: ב־Linux, rmdir "."; בדרך כלל נכשל עם EBUSY או EINVAL בהתאם למערכת הקבצים. אל תסתמך על כך שתוכל להסיר את הספרייה שבה אתה יושב; chdir למקום אחר תחילה.

  • הרשאות: אתה זקוק להרשאת כתיבה + הרצה על ספריית ההורה, לא על הספרייה הנמחקת. הסרת /a/b/c בודקת את המצב של /a/b, לא את זה של /a/b/c.

  • הורה sticky־bit (למשל /tmp): אתה זקוק גם להיות בעלים של הספרייה הנמחקת או להיות בעלים של ההורה; אחרת EPERM.

  • slash גורר: rmdir "foo/" עובד ומשמעו זהה ל־rmdir "foo".

  • race עם תהליך אחר: בין לולאת ה־opendir/readdir שלך וה־rmdir הסופי, תהליך אחר עשוי ליצור קובץ בספרייה. אז תראה ENOTEMPTY למרות שזה עתה רוקנת אותה. נסה שוב או כשל בקול רם - אל תתעלם בשקט.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • mkdir - יוצר ספרייה; הפעולה ההפוכה, עם אותה מוסכמת ארגומנט FILENAME־או־$_

  • unlink - מסיר קבצים (ו־symlinks); rmdir מסיר רק ספריות ריקות

  • chdir - משנה את ספריית העבודה הנוכחית, נמצא בשימוש לעתים קרובות לפני rmdir כדי להימנע מניסיון להסיר את הספרייה שבה אתה נמצא

  • opendir / readdir - רושמים את תוכן הספרייה לפני ריקונה והסרתה

  • $! - מחזיק את ה־errno של rmdir כושל; בדוק ENOENT / ENOTEMPTY / EPERM כדי להסתעף על הסיבה