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

utime#

Ορίζει χρόνους πρόσβασης και τροποποίησης σε μια λίστα αρχείων.

Η utime εφαρμόζει τον αριθμητικό χρόνο πρόσβασης ATIME και χρόνο τροποποίησης MTIME - και τους δύο σε δευτερόλεπτα Unix epoch - σε κάθε αρχείο που κατονομάζεται στη LIST. Είναι η διεπαφή σε επίπεδο Perl προς τις κλήσεις συστήματος utime(2) και utimes(2), και το εργαλείο πίσω από την εντολή Unix touch(1). Ο χρόνος αλλαγής inode (ctime) κάθε αρχείου τίθεται στον τρέχοντα χρόνο ως παρενέργεια - αυτή είναι αναλλοίωτη του πυρήνα, όχι επιλογή της Perl, και δεν μπορεί να κατασταλεί.

Σύνοψη#

utime ATIME, MTIME, LIST
utime undef, undef, LIST      # set both to "now" (since 5.8.0)

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

Ο αριθμός των αρχείων των οποίων οι χρονικές σφραγίδες ενημερώθηκαν επιτυχώς. Όποιο αρχείο δεν μπόρεσε να αγγιχτεί παραλείπεται σιωπηρά από το πλήθος· η $! αντικατοπτρίζει το σφάλμα μόνο από το τελευταίο αρχείο που απέτυχε. Συγκρίνετε την τιμή επιστροφής με scalar @files όταν χρειάζεστε να εντοπίσετε μερική αποτυχία:

my @files = ("a", "b", "c");
my $n = utime $atime, $mtime, @files;
warn "only $n of ", scalar @files, " files updated: $!"
    if $n != @files;

Ορίσματα#

  • ATIME - νέος χρόνος πρόσβασης, σε δευτερόλεπτα από το Unix epoch. Πρέπει να είναι αριθμητικός· τα μη αριθμητικά βαθμωτά εξαναγκάζονται με τον συνήθη τρόπο και μια συμβολοσειρά όπως "now" γίνεται 0 (μεσάνυχτα 1970-01-01).

  • MTIME - νέος χρόνος τροποποίησης, ίδια μορφή.

  • LIST - ένα ή περισσότερα ονόματα αρχείων. Σε συστήματα που υποστηρίζουν την futimes(2) (όπως το Linux), filehandles μπορούν επίσης να εμφανίζονται στη LIST. Τα filehandles πρέπει να περνούν ως globs (*FH) ή ως αναφορές glob (\*FH)· ένα bareword σε εκείνη τη θέση αναλύεται ως όνομα αρχείου, όχι ως handle.

Η μορφή undef, undef#

Από την Perl 5.8.0, το πέρασμα undef και για το ATIME και για το MTIME καλεί την utime(2) με null δεύτερο όρισμα. Ο πυρήνας τότε θέτει και τους δύο χρόνους στον τρέχοντα πραγματικό χρόνο, και - κρίσιμα - αυτή η μορφή πετυχαίνει σε αρχεία που δεν ανήκουν στον καλούντα, εφόσον ο καλών έχει δικαίωμα εγγραφής στο αρχείο. Η απαίτηση ιδιοκτήτη-ή-root ισχύει μόνο για τη μορφή με ρητές χρονικές σφραγίδες.

for my $file (@ARGV) {
    utime undef, undef, $file
        or warn "Couldn't touch $file: $!";
}

Αυτή είναι η μορφή που η πραγματική εντολή touch(1) χρησιμοποιεί εσωτερικά, και είναι η σωστή επιλογή για ένα γενικό σενάριο «touch».

Δικαιώματα#

Δύο διακριτοί κανόνες, ανάλογα με τη μορφή που χρησιμοποιείτε:

Μορφή

Ποιος μπορεί να πετύχει

utime $atime, $mtime, ...

Ιδιοκτήτης αρχείου, ή root

utime undef, undef, ...

Οποιοσδήποτε έχει δικαίωμα εγγραφής στο αρχείο

Ένας μη-ιδιοκτήτης που επιχειρεί τη μορφή με ρητές χρονικές σφραγίδες λαμβάνει EPERM στην $! και το αρχείο μένει ανέπαφο (παρ” όλα αυτά μετράει ως αποτυχία, όχι ως σιωπηρό no-op).

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

Σκέτο Unix-style touch σε λίστα αρχείων που σας ανήκουν:

my $now = time;
utime $now, $now, @ARGV;

Γενικό touch που λειτουργεί επίσης σε αρχεία στα οποία απλώς έχετε δικαίωμα εγγραφής:

for my $file (@ARGV) {
    utime undef, undef, $file
        or warn "Couldn't touch $file: $!";
}

Αντιγραφή χρονικών σφραγίδων από ένα αρχείο σε άλλο μέσω της stat:

my @st = stat $src or die "stat $src: $!";
utime $st[8], $st[9], $dst
    or die "utime $dst: $!";

Touch σε ήδη ανοιχτό filehandle σε Linux (χρειάζεται futimes(2)):

open my $fh, ">>", "log" or die $!;
utime undef, undef, *$fh;       # glob deref, not bareword

Ορισμός αρχείου μία ώρα στο παρελθόν, χρήσιμο για ελέγχους συστήματος build:

my $t = time - 3600;
utime $t, $t, "stale.tmp";

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

  • Ανάμικτο undef και αριθμός: το πέρασμα undef για ένα μόνο από τα δύο πρώτα ορίσματα δεν ενεργοποιεί τη διαδρομή «και-τα-δύο-undef». Το undef εξαναγκάζεται σε 0 (μεσάνυχτα epoch 1970-01-01), η άλλη τιμή χρησιμοποιείται αυτούσια, και ενεργοποιείται προειδοποίηση uninitialized υπό use warnings. Αυτό σχεδόν ποτέ δεν είναι αυτό που θέλετε.

    use warnings;
    utime undef, time, $file;       # atime = 1970-01-01, warning
    
  • Μη αριθμητικές χρονικές σφραγίδες: τα ATIME και MTIME πρέπει να είναι αριθμητικά. Τιμές συμβολοσειράς εξαναγκάζονται - το "1700000000" λειτουργεί· το "yesterday" γίνεται σιωπηρά 0.

  • Ο ctime πάντα μετακινείται: δεν υπάρχει τρόπος να διατηρηθεί ο χρόνος αλλαγής inode ενός αρχείου σε μια κλήση utime. Αν το χρειάζεστε, χρειάζεστε εργαλεία σε επίπεδο συστήματος αρχείων ή στιγμιότυπο, όχι Perl.

  • Filehandle στη LIST: πρέπει να είναι glob (*FH) ή αναφορά glob (\*FH). Ένα bareword όπως FH σε εκείνη τη θέση αναλύεται ως το όνομα αρχείου "FH", και ένα βαθμωτό συμβολοσειράς που κρατά όνομα handle αντιμετωπίζεται ομοίως ως όνομα αρχείου.

  • Ανύπαρκτο αρχείο: μετράει ως αποτυχία και δεν αυξάνει την τιμή επιστροφής· η $! τίθεται σε ENOENT (No such file or directory).

  • Μερική αποτυχία: το πλήθος αντικατοπτρίζει μόνο επιτυχίες. Για να ξέρετε ποιο αρχείο απέτυχε, διατρέξτε τη λίστα ένα τη φορά.

  • Απόκλιση ρολογιού NFS: το ρολόι του διακομιστή είναι το έγκυρο, όχι του πελάτη. Μια αξιοσημείωτη διαφορά μεταξύ των δύο εμφανίζεται ως χρονικές σφραγίδες που δεν ταιριάζουν με ό,τι επέστρεψε η time στον πελάτη.

  • Ακρίβεια κάτω του δευτερολέπτου: η utime της Perl λειτουργεί σε ακέραια δευτερόλεπτα. Συστήματα αρχείων και πυρήνες που υποστηρίζουν χρονικές σφραγίδες nanosecond θα δουν το κλασματικό μέρος να μηδενίζεται. Καταφύγετε στην Time::HiRes::utime (XS) αν χρειάζεστε καλύτερη ανάλυση.

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

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

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

  • stat - διαβάζει τις χρονικές σφραγίδες που γράφει η utime· στοιχεία 8 (atime), 9 (mtime) και 10 (ctime) της επιστρεφόμενης λίστας

  • time - τρέχοντα δευτερόλεπτα epoch, η συνήθης πηγή και για το ATIME και για το MTIME

  • open και close - filehandles που μπορεί να αγγίξει η utime σε συστήματα με futimes(2)

  • $! - σφάλμα συστήματος από το τελευταίο αρχείο που απέτυχε όταν το πλήθος επιστροφής είναι μικρότερο από scalar @files

  • utime(2), utimes(2), futimes(2) - οι υποκείμενες κλήσεις συστήματος