Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set file last modified file attribute in Perl

Tags:

perl

Here I use last_run file stored in the local directory and update it's last modified date if it's not equal to the current datetime. Is it possible not to write a symbol into the file, but to update mtime in some other way?

I saw that there is a module File::Touch, but I don't want to use it as I already have an opened file, and it will be faster to use the file descriptor as is.

#!/usr/bin/perl

use utf8;
use strict;
use warnings;

use File::stat;
use DateTime;

my $file_name = "last_run";
if (-e $file_name)
{
    my $fh;
    if (open($fh, "+<", $file_name))
    {
        my $timestamp = stat($fh)->mtime;
        my $now = DateTime->now(time_zone => 'local');

        my ($sec, $min, $hour, $day, $month, $year) = localtime($timestamp);
        $month += 1;
        $year += 1900;

        if ($now->day != $day or $now->month != $month or $now->year != $year)
        {
            print $fh ' '; # <- I have to write something into the file
        }

        print "$day $month $year\n";
        print $now->day.' '.$now->month.' '.$now->year."\n";
    }
    else
    {
        print "cannot open +< $file_name: $!";
    }

    close($fh);
}
else
{
    open(my $fh, ">", $file_name)
        or print "cannot open > file name: $!";
}
like image 990
user4035 Avatar asked Sep 05 '25 03:09

user4035


1 Answers

You're looking for the utime function.

Some quotes from the documentation:

Changes the access and modification times on each file of a list of files. The first two elements of the list must be the NUMERIC access and modification times, in that order. Returns the number of files successfully changed. The inode change time of each file is set to the current time.

Since Perl 5.8.0, if the first two elements of the list are undef, the utime(2) syscall from your C library is called with a null second argument. On most systems, this will set the file's access and modification times to the current time.

On systems that support futimes(2), you may pass filehandles among the files. On systems that don't support futimes(2), passing filehandles raises an exception. Filehandles must be passed as globs or glob references to be recognized; barewords are considered filenames.


So, something like:

utime undef, undef, $fh;

will update the file's modification (And access) time to the current one. If you're not using most systems, there's another example in the documentation that explicitly uses the current time.

futimes(2) is present on Linux and BSDs. If you're using a different OS, you'll have to use the filename instead of handle.

like image 187
Shawn Avatar answered Sep 08 '25 18:09

Shawn