The issue is that the -atime
, -ctime
and -mtime
options do some unexpected rounding. The explanation is in man find
under -atime
:
-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.
There are alternatives in modern versions of find
:
-mmin
(and variants) round to the minute, not to the day.
So -mmin "+$(( 60*24*2 ))"
works based on current time of day 2 days ago.
-daystart
measures times based on 00:00:00 of the current day.
That is a fairly blunt instrument,
and is sensitive to the order of options on the command line.
If you are on a system without these recent extensions to find
(e.g., Solaris or AIX),
or don't want all your housekeeping to have an enforced midnight cutoff,
and don't want a different cutoff time every time you execute,
using a reference file is a good alternative.
Paul--) touch -t 202009020301 FileToRetain
Paul--) touch -t 202009020300 FileOnCusp
Paul--) touch -t 202009020259 FileToDelete
Paul--)
Paul--) touch /tmp/myRefFile -t $( date -d '4 days ago' '+%Y%m%d0300' )
Paul--) ls -ltr /tmp/myRefFile .
-rw-r--r-- 1 paul paul 0 Sep 2 03:00 /tmp/myRefFile
.:
total 0
-rw-r--r-- 1 paul paul 0 Sep 2 02:59 FileToDelete
-rw-r--r-- 1 paul paul 0 Sep 2 03:00 FileOnCusp
-rw-r--r-- 1 paul paul 0 Sep 2 03:01 FileToRetain
Paul--) find . -type f ! -newer /tmp/myRefFile -delete
Paul--) ls -ltr /tmp/myRefFile .
-rw-r--r-- 1 paul paul 0 Sep 2 03:00 /tmp/myRefFile
.:
total 0
-rw-r--r-- 1 paul paul 0 Sep 2 03:01 FileToRetain
Paul--)
The reference file should not be in the directory being cleansed (it might delete itself at an interesting moment), and in production you should probably use mktemp
or put the PID as part of the name to avoid problems with concurrent uses, and rm
it afterwards.
Of course, if you do not have modern find
, then you probably don't have date -d
either. My housekeeping was on a monthly basis, so on Solaris one has to script month/year overflow but not month-end or leap-year – just set dd=01. But aligning to specific day in week or month is something else that find
by itself cannot do cleanly: date -d 'last Sunday 06:00'
is helpful as a reference file.
find
include in its output the files that are more than two days old?touch
a reference file with the precise timestamp I want, and then compare withfind ! -newer myRefFile
.