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

chmod#

Αλλάζει τα bits δικαιωμάτων μιας λίστας αρχείων.

Η chmod ορίζει σε κάθε αρχείο της LIST τα δικαιώματα MODE. Η MODE είναι αριθμητική τιμή - τα δώδεκα κατώτερα bits είναι η συνηθισμένη τριάδα δικαιωμάτων του Unix συν τα bits setuid, setgid και sticky, ακριβώς όπως τα δέχεται η chmod(2). Η LIST δέχεται τόσο απλά ονόματα διαδρομής όσο και ανοιχτά filehandles. Επιστρέφει τον αριθμό των αρχείων για τα οποία πέτυχε η υποκείμενη κλήση συστήματος.

Σύνοψη#

chmod MODE, LIST

Τι επιστρέφεται#

Ο αριθμός των αρχείων που άλλαξαν με επιτυχία, ως ακέραιος. Το μηδέν σημαίνει ότι κάθε κλήση απέτυχε· τιμή μικρότερη του scalar @files σημαίνει μερική αποτυχία. Η chmod δεν εκτοξεύει εξαίρεση σε αποτυχία επιμέρους αρχείου - συνεχίζει και αθροίζει τις επιτυχίες.

Η $! αντικατοπτρίζει το σφάλμα μόνο από το τελευταίο αρχείο που απέτυχε. Σε μια εκτέλεση με ανάμικτη επιτυχία/αποτυχία δεν υπάρχει ενσωματωμένος τρόπος να μάθετε ποια αρχεία απέτυχαν· αν χρειάζεστε αναφορά σφαλμάτων ανά αρχείο, καλέστε την chmod μία φορά ανά αρχείο και ελέγξτε την τιμή επιστροφής κάθε φορά:

for my $f (@files) {
    chmod 0644, $f
        or warn "chmod $f: $!";
}

Σωστή σύνταξη της MODE#

Η MODE είναι ακέραιος. Οι τρεις τρόποι να γραφτεί:

  • Οκταδικό κυριολεκτικό με αρχικό μηδέν: 0644, 0755, 0600. Αυτή είναι η συμβατική μορφή και αντιστοιχεί στα ψηφία που θα πληκτρολογούσατε στην chmod(1).

  • Οκταδικό κυριολεκτικό με πρόθεμα 0o: 0o644, 0o755. Γίνεται δεκτό από την Perl 5.34 και μετά· ισοδύναμο με τη μορφή αρχικού μηδενός και πιο εύκολο να διαβαστεί ως «οκταδικό» με μια ματιά.

  • Συμβολικές σταθερές από το Fcntl: η έκφραση use Fcntl qw(:mode); S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH αποτιμάται σε 0755. Χρήσιμο όταν ένα σύνολο δικαιωμάτων χτίζεται από επιμέρους κομμάτια.

Ένα όρισμα συμβολοσειράς είναι σχεδόν πάντα σφάλμα:

chmod "0644", "foo";     # WRONG - stringifies as decimal 644 (octal 1204),
                         #         grants mode --w----r-T
chmod 644,    "foo";     # WRONG - decimal 644 is octal 1204, same result
chmod 0644,   "foo";     # right
chmod 0o644,  "foo";     # right (Perl 5.34+)

Αν η mode έρχεται πραγματικά ως συμβολοσειρά (αρχείο διαμόρφωσης, όρισμα CLI), μετατρέψτε την πρώτα με την oct:

my $mode = "0644";       # string from config
chmod oct($mode), "foo"; # oct("0644") == 0644

Καθολική κατάσταση που επηρεάζει#

Ορίζει την $! σε οποιαδήποτε αποτυχία ώστε να αντιστοιχεί στην τελευταία αποτυχημένη κλήση chmod(2) / fchmod(2). Δεν διαβάζει καθολικές μεταβλητές του διερμηνέα.

Παραδείγματα#

Αλλαγή ενός αρχείου, έλεγχος επιτυχίας:

chmod 0755, "install.sh"
    or die "chmod install.sh: $!";

Αλλαγή πολλών αρχείων σε μία κλήση, αποτύπωση του πλήθους:

my $cnt = chmod 0644, "a.txt", "b.txt", "c.txt";
print "updated $cnt of 3 files\n";

Με πίνακα ονομάτων διαδρομής:

my @executables = glob "bin/*";
chmod 0755, @executables;

Διατήρηση των υπαρχόντων bits, προσθήκη δικαιώματος εγγραφής για τον ιδιοκτήτη. Διαβάζει την mode με την stat, εφαρμόζει μάσκα για τα bits δικαιωμάτων, κάνει OR με το νέο bit και την γράφει πίσω:

open my $fh, "<", "foo" or die $!;
my $perm = (stat $fh)[2] & 07777;
chmod $perm | 0200, $fh;

Συμβολική μορφή μέσω του Fcntl:

use Fcntl qw(:mode);
chmod S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, @executables;
# identical to: chmod 0755, @executables;

Αναφορά σφαλμάτων ανά αρχείο (χρειάζεται για να μάθετε ποιο αρχείο απέτυχε σε κλήση πολλαπλών αρχείων):

my @failed;
for my $f (@files) {
    push @failed, $f unless chmod 0644, $f;
}
warn "chmod failed on: @failed\n" if @failed;

Οριακές περιπτώσεις#

  • Κενή λίστα: η chmod 0644 επιστρέφει 0. Η mode αποτιμάται αλλά δεν γίνεται καμία κλήση συστήματος.

  • Modes ως συμβολοσειρά: τόσο η chmod "0644", $f όσο και η chmod "+x", $f είναι λανθασμένες. Η chmod δεν αναλύει ποτέ συμβολικές συμβολοσειρές mode - σε αντίθεση με την chmod(1), η ενσωματωμένη συνάρτηση παίρνει αριθμό, όχι προδιαγραφή.

  • Filehandles έναντι barewords: ένα bareword στη LIST είναι όνομα αρχείου, όχι filehandle. Περάστε ένα filehandle ως glob ή ως αναφορά glob:

    chmod 0644, *FH;         # filehandle
    chmod 0644, \*FH;        # filehandle
    chmod 0644, $fh;         # filehandle (lexical)
    chmod 0644, "FH";        # filename "FH" - almost certainly a bug
    

    Σε συστήματα χωρίς fchmod(2), το πέρασμα filehandle εκπέμπει εξαίρεση. Το Linux υποστηρίζει την fchmod(2), οπότε στις πλατφόρμες-στόχους της pperl αυτό λειτουργεί πάντα.

  • Bits setuid / setgid / sticky: τα τρία ανώτερα bits της λέξης mode (04000, 02000, 01000) θέτουν αντίστοιχα setuid, setgid και το sticky bit. Το 0o4755 δημιουργεί setuid εκτελέσιμο· το 0o2775 έναν setgid κατάλογο.

  • Symlinks: chmod follows symlinks. Changing permissions on the symlink itself is not portable and is not exposed by this built-in

    • use lchmod from a module if the platform supports it.

  • Δικαίωμα αλλαγής δικαιωμάτων: μόνο ο ιδιοκτήτης του αρχείου (και ο root) μπορούν να καλέσουν την chmod(2) σε ένα αρχείο. Η αποτυχία θέτει την $! σε EPERM.

  • Ανύπαρκτες διαδρομές: η chmod σε ανύπαρκτη διαδρομή θέτει την $! σε ENOENT και συνεισφέρει 0 στο πλήθος επιτυχιών. Δεν προειδοποιεί ούτε τερματίζει.

  • Η umask δεν εφαρμόζεται: η umask μασκάρει τη mode νεοδημιουργημένων αρχείων από τις open, sysopen, mkdir και παρόμοιες. Η chmod ορίζει τη mode κυριολεκτικά - χωρίς μασκάρισμα.

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

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

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

  • chown - η αδελφή κλήση για αλλαγή ιδιοκτήτη/ομάδας· ίδια μορφή λίστας-και-επιστροφής-πλήθους

  • stat - διαβάστε την τρέχουσα mode ώστε να την τροποποιήσετε αντί να την αντικαταστήσετε εξ ολοκλήρου

  • umask - προεπιλεγμένη μάσκα δικαιωμάτων που εφαρμόζεται σε νέα αρχεία· άσχετη με την chmod, η οποία θέτει τα bits κυριολεκτικά

  • open / sysopen - δημιουργούν αρχεία· το όρισμα mode της sysopen μασκάρεται από την umask κατά τη δημιουργία και κατόπιν μπορεί να γίνει πιο αυστηρό ή πιο χαλαρό με την chmod

  • oct - αναλύει το "0644" στον ακέραιο 0644 όταν η mode έρχεται ως συμβολοσειρά

  • $! - σφάλμα συστήματος από το τελευταίο αρχείο που απέτυχε· έχει νόημα μόνο για κλήσεις ενός αρχείου ή αμέσως μετά από αποτυχημένη κλήση ανά αρχείο μέσα σε βρόχο