Filehandles, αρχεία, κατάλογοι

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 (ορισμένα BSDs χρησιμοποιούν EEXIST). Αυτό είναι η μακράν πιο συνηθισμένη αποτυχία της rmdir. Καταγράψτε τα περιεχόμενα του καταλόγου ή καλέστε την remove_tree αν στην πραγματικότητα θέλετε αναδρομική διαγραφή.

  • Χωρίς όρισμα: η rmdir χωρίς όρισμα χρησιμοποιεί το $_, όχι το @ARGV ούτε τον τρέχοντα κατάλογο. Η γραφή rmdir() με κενές παρενθέσεις είναι το ίδιο με rmdir χωρίς όρισμα - εξακολουθεί να διαβάζει το $_.

  • Symlink προς κατάλογο: η rmdir αρνείται να αφαιρέσει symlinks· λειτουργεί μόνο σε καταλόγους. Χρησιμοποιήστε unlink στο ίδιο το symlink. Το $! τυπικά τίθεται σε ENOTDIR.

  • Τρέχων κατάλογος εργασίας: Στο Linux, η rmdir "."; συνήθως αποτυγχάνει με EBUSY ή EINVAL ανάλογα με το σύστημα αρχείων. Μη βασίζεστε στο ότι μπορείτε να αφαιρέσετε τον κατάλογο στον οποίο βρίσκεστε· κάντε πρώτα chdir αλλού.

  • Δικαιώματα: χρειάζεστε δικαίωμα εγγραφής + εκτέλεσης στον γονικό κατάλογο, όχι στον κατάλογο που αφαιρείται. Η αφαίρεση του /a/b/c ελέγχει το mode του /a/b, όχι του /a/b/c.

  • Γονέας με sticky bit (π.χ. /tmp): πρέπει επίσης να είστε κάτοχος του καταλόγου που αφαιρείται ή κάτοχος του γονέα· διαφορετικά EPERM.

  • Τελική κάθετος: η rmdir "foo/" λειτουργεί και σημαίνει το ίδιο με rmdir "foo".

  • Κούρσα με άλλη διεργασία: μεταξύ του βρόχου opendir/readdir σας και της τελικής rmdir, μια άλλη διεργασία μπορεί να δημιουργήσει αρχείο στον κατάλογο. Θα δείτε τότε ENOTEMPTY παρά το ότι μόλις τον αδειάσατε. Δοκιμάστε ξανά ή αποτύχετε με θόρυβο - μην το αγνοήσετε σιωπηρά.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • mkdir - δημιουργεί κατάλογο· η αντίστροφη λειτουργία, με την ίδια σύμβαση ορίσματος FILENAME-ή-$_

  • unlink - αφαιρεί αρχεία (και symlinks)· η rmdir αφαιρεί μόνο κενούς καταλόγους

  • chdir - αλλάζει τον τρέχοντα κατάλογο εργασίας, συχνά χρησιμοποιείται πριν από rmdir για να αποφύγετε την προσπάθεια αφαίρεσης του καταλόγου στον οποίο βρίσκεστε

  • opendir / readdir - καταγράφει τα περιεχόμενα ενός καταλόγου πριν τον αδειάσετε και τον αφαιρέσετε

  • $! - κρατά το errno αποτυχημένης rmdir· ελέγξτε για ENOENT / ENOTEMPTY / EPERM για να διακλαδώσετε βάσει του λόγου