brain hurt and file test

Tom Phoenix rb-pdx-pm at
Thu Jun 13 16:31:38 CDT 2002

On 13 Jun 2002, Randal L. Schwartz wrote:

>         $^T = time - 30;
>         if (-A $file > 0) {
>                 # file was last modified more than 30 secs ago
>         }
> would be a cheap way to do this without scaling for days/seconds. :)

Just in case there's any confusion between the code and the comment: It's
-M to get the "modification age" and -A to get the "accessed age". Randal
knows this stuff so well that sometimes he doesn't read the comments. :-)

As a rule of thumb, when thinking about -M, -A, and -C, you should nearly
always use -M, which tells you "how old is the data in this file", or "how
long has it been since this file was updated". The mtime (which is the
underlying timestamp value used by Perl to calculate the -M value) is the
timestamp used by 'ls -l' and make, and it's what most people think of as
the "age" of the file. When in doubt, go with -M.

Rarely you'll want -A, which tells you "how long has it been since
somebody bothered looking at this data". That's mostly useful in
identifying abandoned, junk files, like those in /tmp directories. If a
file's atime is from last year, it's a pretty good guess that it doesn't
contain frequently-accessed data. (There should be an option to grep to
leave atimes unchanged when a grep fails, but I've never heard of a grep
that has that option -- so, if you grep (even unsuccessfully) through a
bunch of files, you're whacking their atimes.) But here's a real-world use
for the atime: If one of your web pages (or images, or whatever) has an
atime that's old, probably none of your active pages links to it. (Fans of
old British comedies would ask that file, "Are you being served?")

The -C filetest is almost never what you want. For those who really need
to know, it's telling you "how long has it been since anything important
(like its name, permissions, contents) changed about this file". The ctime
is used for incremental backups; if the ctime is older than your previous
incremental backup, you can skip this one. If you're not doing incremental
backups, you can probably skip this one, too.

One more confusing wrinkle. When you read from a file, the atime is always
updated to the current time. When you write to a file, the mtime is always
updated. That's simple. The catch is that (and somebody correct me if I'm
wrong here) on some-but-not-all systems, when you write to a file, the
system updates the mtime and ALSO the atime, as if you had read from the
file as well. (There's a good reason for doing that, but I don't feel like
setting out both sides of a moot argument here. This is almost a FMTEYEWTK
as it is.)

Check your machine's stat(2) for the honest truth about the three
timestamps. And don't forget that, as somebody else pointed out, Perl's
stat(), time, and $^T all use timestamps (numbers like 1024001900, always
positive integers, usually up in the hundreds of millions or more), but -M
and friends give ages in days (numbers like 3.14159, rarely integers,
sometimes negative, not often larger than a few thousand). Of course, it's
easy to work with either of these kinds of numbers, although it's best to
use a module when things get tricky.

    my $mtime = -M $file;		# age in days
    my $secs = 24 * 60 * 60 * $mtime;	# age in secs
    print "That file is around $secs seconds old.\n";

--Tom "secs on my mind" Phoenix


More information about the Pdx-pm-list mailing list