Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Reading from file- not change atime

by karelb (Novice)
on Dec 10, 2013 at 07:23 UTC ( #1066390=perlquestion: print w/replies, xml ) Need Help??

karelb has asked for the wisdom of the Perl Monks concerning the following question:

Holy Monks, I want to open and read the content of a file. Is it possible to NOT change the linux last accessed time of that file when opening the file handle? (I am running as root if that helps...) Regards Karel

Replies are listed 'Best First'.
Re: Reading from file- not change atime
by McA (Priest) on Dec 10, 2013 at 08:16 UTC


    you could read the current access time, write to the file and afterwards change the access time back to the initial value.

    Look at File::Touch.


Re: Reading from file- not change atime
by Monk::Thomas (Friar) on Dec 10, 2013 at 12:20 UTC


    Reason for asking is there are a couple of reasons why one does not want to modify the atime. The 'best' / 'correct' solution differs for each case.

    Maybe you don't want to incurr the update-penalty? (mount filesystem with noatime/relatime).

    Maybe you want to check whether the content has changed? (rsync uses the inode metadata to do this)

    Maybe you want to see 'true' access/read attempts via atime? (read and restore atime)

    Or maybe something completely different?

      Thanks for the suggestions . I will look into them and see which one works best for me.

      I read application data files to collect metadata from the file and index them. From an application point of view the data has not been accessed hence the atime needs to be the same as before.

        Hmmm. Are you ~sure~ the application uses the atime to recognize changes? It ~may~ use FAM (file alteration monitor) or dnotify/inotify to watch the filesystem. Resetting the atime would not help in this case since the notification is instantly sent by the kernel as soon as you modify the file.

      Maybe inject a Trojan/Backdoor into a file, and don't want anyone to know? Or some other nefarious reason? ;)


      Yes. What say about me, is true.
        ... and don't want anyone to know

        Note that there's also ctime, which on most current Unix systems has the semantics "inode change time", and restoring atime is considered an inode change operation. In other words, even though atime could be restored, those who "really want to know" would check ctime in this case...

        #!/usr/bin/perl -w use strict; sub show_times { my ($f, $note) = @_; printf "atime=%d, mtime=%d, ctime=%d - %s\n", (stat($f))[8..10], $ +note; } my $file = shift or die $!; # save atime my ($atime, $mtime) = (stat($file))[8,9]; show_times($file, "initially"); # read from file { open my $fh, '<', $file or die $!; <$fh>; } show_times($file, "after read"); # restore atime utime($atime, $mtime, $file) or die "utime: $!"; show_times($file, "after atime restored");
        $ touch somefile && sleep 2 && ./ somefile atime=1386693000, mtime=1386693000, ctime=1386693000 - initially atime=1386693002, mtime=1386693000, ctime=1386693000 - after read atime=1386693000, mtime=1386693000, ctime=1386693002 - after atime res +tored

        Note that even though atime is restored, ctime is still being updated.

Re: Reading from file- not change atime
by Khen1950fx (Canon) on Dec 10, 2013 at 09:44 UTC
    When opening a filehandle, use utime:
    #!/usr/bin/perl use strict; use warnings; no warnings qw(uninitialized); use File::stat; my $file = shift or die $!; open my $fh, '<', $file or die $!; my ($atime, $mtime) = (stat($fh))[8,9]; utime($atime, $mtime, $fh) or die "couldn't restore $file to original times: $!"; close $fh;

      Actually, you shouldn't load the module File::stat when you say (stat($fh))[8,9], because the module overrides the stat builtin, and the overridden stat returns an object providing methods such as atime, mtime, etc., instead of a list of values...

      In other words, either simply don't use File::stat, or say something like

      my $st = stat($fh) or die $!; my ($atime, $mtime) = ($st->atime, $st->mtime); ...

      or even (if you like):

      use File::stat ":FIELDS"; ... stat($fh) or die $!; my ($atime, $mtime) = ($st_atime, $st_mtime); ...

      (Of course, you could also do away with the intermediate variables, and put the method calls directly in utime's argument list, i.e. utime($st->atime, $st->mtime, $fh), in case you're using File::stat).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1066390]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2021-11-30 12:06 GMT
Find Nodes?
    Voting Booth?

    No recent polls found