How to set (find) atime in seconds

command linefilesfindtimestamps

How do I set -atime in milliseconds, seconds, or minutes? The default is days:

-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.

I'd like to run a cron job, say, hourly to check if files in a particular directory have been accessed within that time frame. Entering time as a decimal doesn't seem to work, i.e.

find . -atime 0.042 -print

But maybe there is a better solution anyway – another command perhaps? Or perhaps this can't be done.. for finding files modified in last x minutes there is -mmin that allows setting the time in minutes. Perhaps the absence of such option for the access time implies that information is not stored the same way?

I'm using Ubuntu 16.04.

Best Answer

Note that when you do -mtime <timespec>, the <timespec> checks the age of the file at the time find was started.

Unless you run it in a very small directory tree, find will take several milliseconds (if not seconds or hours) to crawl the directory tree and do a lstat() on every file. So having a precision of shorter than a second doesn't necessarily make a lot of sense.

Also note that not all file systems support time stamps with subsecond granularity.

Having said that, there are a few options.

With the find of many BSDs and the one from schily-tools, you can do:

find . -atime -1s

To find files that have been last accessed less than one second ago (compared to when find was started).

With zsh:

ls -ld -- **/*(Dms-1)

For subsecond granularity, with GNU tools, you can use a reference file whose atime you set with touch:

touch -ad '0.5 seconds ago' ../reference
find . -anewer ../reference

Or with recent versions of perl:

perl -MTime::HiRes=lstat,clock_gettime -MFile::Find -le '
  $start =  clock_gettime(CLOCK_REALTIME) - 0.5;
  find(
    sub {
      my @s = lstat $_;
      print $File::Find::name if @s and $s[8] > $start
    }, ".")'
Related Question