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

stat#

Λαμβάνει τις πληροφορίες κατάστασης ενός αρχείου.

Η stat ζητά από το λειτουργικό σύστημα την εγγραφή μεταδεδομένων ενός αρχείου - μέγεθος, ιδιοκτησία, δικαιώματα, χρονικές σφραγίδες, inode - και την επιστρέφει ως λίστα 13 στοιχείων. Είναι η υποκείμενη πρωτογενής συνάρτηση πίσω από τους ελέγχους αρχείων -X (-e, -f, -r, …), πίσω από αρθρώματα όπως το File::stat, και πίσω από κάθε σενάριο που χρειάζεται να εξετάσει ένα αρχείο χωρίς να το ανοίξει. Η stat αποαναφέρει τα συμβολικά λινκ και αναφέρει για τον στόχο· χρησιμοποιήστε lstat για να λάβετε το ίδιο το λινκ.

Σύνοψη#

stat FILEHANDLE
stat EXPR
stat DIRHANDLE
stat
stat _

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

Σε περιβάλλον λίστας, μια λίστα 13 αριθμητικών πεδίων. Σε βαθμωτό περιβάλλον, λογική τιμή: αληθές σε επιτυχία, ψευδές σε αποτυχία. Σε κάθε περίπτωση, σε επιτυχία ο ενταμιευτής stat του πυρήνα αποθηκεύεται στο ειδικό filehandle _, το οποίο οποιαδήποτε επόμενη stat, lstat ή έλεγχος -X μπορεί να επαναχρησιμοποιήσει χωρίς νέα κλήση συστήματος.

Σε αποτυχία, το περιβάλλον λίστας επιστρέφει την κενή λίστα και το $! ορίζεται στην τιμή errno από την αποτυχημένη stat(2).

Τα πεδία, με τη σειρά:

Δείκτης

Πεδίο

Σημασία

0

dev

αριθμός συσκευής του συστήματος αρχείων που περιέχει το αρχείο

1

ino

αριθμός inode

2

mode

mode αρχείου - bits τύπου και bits δικαιωμάτων μαζί

3

nlink

αριθμός σκληρών συνδέσμων προς το αρχείο

4

uid

αριθμητικό user ID του ιδιοκτήτη

5

gid

αριθμητικό group ID του ιδιοκτήτη

6

rdev

αναγνωριστικό συσκευής, για ειδικά αρχεία χαρακτήρα/μπλοκ

7

size

συνολικό μέγεθος σε bytes

8

atime

χρόνος τελευταίας πρόσβασης, δευτερόλεπτα από το epoch (1970-01-01 00:00 GMT)

9

mtime

χρόνος τελευταίας τροποποίησης, δευτερόλεπτα από το epoch

10

ctime

χρόνος αλλαγής inode, δευτερόλεπτα από το epoch - όχι χρόνος δημιουργίας

11

blksize

προτιμώμενο μέγεθος μπλοκ I/O για αναγνώσεις/εγγραφές σε αυτό το αρχείο

12

blocks

αριθμός μπλοκ συστήματος αρχείων που έχουν πραγματικά εκχωρηθεί (συχνά 512 B το καθένα)

Το πεδίο 2 (mode) πακετάρει τόσο τον τύπο αρχείου όσο και τα bits δικαιωμάτων σε έναν αριθμό. Μασκάρετε με 07777 για να δείτε μόνο τα δικαιώματα· χρησιμοποιήστε τις σταθερές S_IF* και τους βοηθούς S_IS* από το Fcntl για να ελέγξετε τον τύπο φορητά.

my $mode = (stat($filename))[2];
printf "permissions are %04o\n", $mode & 07777;

Δεν συμπληρώνει κάθε σύστημα αρχείων κάθε πεδίο. Τα atime, blksize, και blocks μπορεί να επιστρέψουν 0 σε συστήματα αρχείων που δεν τα παρακολουθούν (για παράδειγμα ορισμένες προσαρτήσεις FUSE ή δικτυακά συστήματα αρχείων)· το ctime δεν είναι φορητός «χρόνος δημιουργίας» - παρακολουθεί την τελευταία αλλαγή του ίδιου του inode (δικαιώματα, ιδιοκτησία, πλήθος συνδέσμων), όχι το πότε δημιουργήθηκε αρχικά το αρχείο.

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

  • $_ - διαβάζεται όταν η stat καλείται χωρίς όρισμα. Η stat χωρίς EXPR εκτελεί stat στο όνομα αρχείου που κρατά το $_, όχι στο αποθηκευμένο handle _.

  • $! - ορίζεται στο errno της αποτυχημένης κλήσης συστήματος stat(2) όταν η κλήση αποτυγχάνει.

  • Το ειδικό filehandle _ - μια cache ανά διερμηνέα του πιο πρόσφατου επιτυχημένου αποτελέσματος stat, lstat ή -X. Η μετάδοση του _ ως όρισμα επαναχρησιμοποιεί αυτόν τον αποθηκευμένο ενταμιευτή και δεν εκδίδει κλήση συστήματος. Επιτυχημένες κλήσεις τον ανανεώνουν· αποτυχημένες αφήνουν τα προηγούμενα περιεχόμενα στη θέση τους.

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

Βασικό ξεπακετάρισμα σε περιβάλλον λίστας:

my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
    $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);

Επιλογή ενός μόνο πεδίου με τομή λίστας:

my $size  = (stat($filename))[7];
my $mtime = (stat($filename))[9];

Βαθμωτό περιβάλλον ως ανίχνευση ύπαρξης συν αναγνώσιμων μεταδεδομένων:

if (stat($path)) {
    my $size = (stat _)[7];          # reuse the cached buffer
    print "size = $size\n";
} else {
    warn "stat $path: $!";
}

Επαναχρησιμοποίηση της cache σε έλεγχο -X και σε stat:

if (-x $file && (($d) = stat(_)) && $d < 0) {
    print "$file is executable NFS file\n";
}

Πρόσβαση με ονοματισμένους accessor μέσω του File::stat:

use File::stat;
my $sb = stat($filename);
printf "file %s, size %s, perm %04o, mtime %s\n",
       $filename, $sb->size, $sb->mode & 07777,
       scalar localtime $sb->mtime;

Αποκωδικοποίηση του mode με Fcntl:

use Fcntl ':mode';
my $mode = (stat($filename))[2];
printf "permissions %04o\n", S_IMODE($mode);
print "is a directory\n" if S_ISDIR($mode);

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

  • Χωρίς όρισμα: το stat; κάνει stat στο $_, όχι στο αποθηκευμένο handle _. Για να ξαναδιαβάσετε την cache πρέπει να γράψετε stat(_) με την κάτω παύλα ως ρητό bareword.

  • Το bareword _ είναι ειδικό: ονομάζει την cache του stat, όχι αρχείο. Η τοποθέτησή του σε εισαγωγικά (stat("_")) κάνει stat σε ένα αρχείο που λέγεται κυριολεκτικά _ στον τρέχοντα κατάλογο.

  • Τα συμβολικά λινκ ακολουθούνται: η stat αναφέρει για τον στόχο ενός συμβολικού λινκ. Για το ίδιο το λινκ, χρησιμοποιήστε lstat. Ένα σπασμένο symlink κάνει την stat να αποτύχει με ENOENT· η lstat στο ίδιο μονοπάτι επιτυγχάνει.

  • Μορφή DIRHANDLE: η μετάδοση handle καταλόγου από opendir επιστρέφει το stat του ίδιου του ανοιχτού καταλόγου. Δεν υποστηρίζουν όλες οι πλατφόρμες αυτό· σε όσες δεν το υποστηρίζουν, η κλήση αποτυγχάνει και το $! ορίζεται.

  • Οι αριθμοί inode μπορεί να υπερχειλίσουν τους ακεραίους: σε συστήματα αρχείων με αριθμούς inode 64 bit πέρα από το εύρος ακεραίων της Perl, το ino επιστρέφεται ως δεκαδική συμβολοσειρά για να διατηρηθεί η πλήρης τιμή. Συγκρίνετε αριθμούς inode με eq, όχι ==, για να παραμείνετε σωστοί σε αυτά τα συστήματα αρχείων. Το eq λειτουργεί μια χαρά και σε αριθμητικά inode.

  • Το ctime δεν είναι χρόνος δημιουργίας: είναι ο χρόνος αλλαγής inode - ενημερώνεται από chmod, chown, rename, αλλαγές πλήθους συνδέσμων, και τις ίδιες τις εγγραφές του αρχείου. Το Linux εκθέτει έναν πραγματικό χρόνο δημιουργίας (btime) μέσω της statx(2), αλλά αυτός δεν αποτελεί μέρος της λίστας επιστροφής της stat.

  • Μηδενικά πεδία σε ορισμένα συστήματα αρχείων: τα atime (σε προσαρτήσεις noatime), blksize, και blocks μπορεί να αναφερθούν ως 0. Αντιμετωπίστε το 0 ως «μη διαθέσιμο», όχι ως νοηματική τιμή.

  • Το βαθμωτό περιβάλλον δεν συμπληρώνει το _ σε αποτυχία: μια αποτυχημένη stat αφήνει τον προηγούμενο αποθηκευμένο ενταμιευτή ανέπαφο. Ελέγχετε πάντα την τιμή επιστροφής πριν από επόμενο stat(_) ή -X _.

  • Παράθυρα race: τα μεταδεδομένα που επιστρέφονται είναι στιγμιότυπο. Οτιδήποτε ενεργεί σε μονοπάτι βασισμένο στο αποτέλεσμα της stat (έλεγχοι δικαιωμάτων, μοτίβα TOCTOU) πρέπει να γραφτεί ώστε να ανέχεται την αλλαγή του αρχείου μεταξύ της stat και της επόμενης πράξης - ή καλύτερα, ανοίξτε πρώτα το αρχείο και κάντε stat στο filehandle.

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

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

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

  • lstat - όπως η stat αλλά δεν ακολουθεί συμβολικά λινκ· αναφέρει για το ίδιο το λινκ

  • Τελεστές ελέγχου αρχείων -X (-e, -f, -r, -w, -x, …) - κτισμένοι πάνω στον ίδιο ενταμιευτή stat· μοιράζονται την cache _ με τις stat και lstat

  • chmod - αλλάζει τα bits δικαιωμάτων που αναφέρονται στο πεδίο 2 (mode)

  • chown - αλλάζει τα uid και gid που αναφέρονται στα πεδία 4 και 5

  • File::stat - ονοματισμένοι accessor ($sb->size, $sb->mtime, …) πάνω από την ίδια λίστα 13 πεδίων· το use File::stat υπερκαλύπτει την stat στην τρέχουσα εμβέλεια

  • Fcntl - η ετικέτα :mode εξάγει τις σταθερές S_I* και τους βοηθούς S_IS* για την αποκωδικοποίηση του πεδίου 2