find 的 -mtime 到底怎么算,我照着实测结果记一遍
上个月写日志清理脚本,用的是 find /data/logs -name '*.log' -mtime +2 -delete。跑完发现当天的日志还在,前天的没了,可前一天那份也没了——我原本以为 +2 是"两天以前",也就是前天及更早。
后来才想明白,问题出在 -mtime 那个"取整"上。
GNU find 的规则是:把文件修改时间到当前时间这段间隔,按 24 小时为一个单位向下取整,得到的天数就是 -mtime n 里的 n。所以一个改了 2.9 天的文件,算出来是 2;+2 表示"大于 2",整数里就是 3 及以上;-2 表示"小于 2",也就是 0 和 1。
光看文字还是容易记混,我在 openEuler 22.03 上造了几个不同时间点的文件实测了一遍。
mkdir -p /tmp/mt && cd /tmp/mt
touch -d '0 hours ago' f0
touch -d '36 hours ago' f1
touch -d '60 hours ago' f2
touch -d '84 hours ago' f3
touch -d '108 hours ago' f4
分别是 0、1.5、2.5、3.5、4.5 天。然后:
find /tmp/mt -maxdepth 1 -type f -mtime 2
# /tmp/mt/f2 ← 60 小时,取整为 2
find /tmp/mt -maxdepth 1 -type f -mtime +2
# /tmp/mt/f3
# /tmp/mt/f4 ← 只有 3.5 天和 4.5 天的
find /tmp/mt -maxdepth 1 -type f -mtime -2
# /tmp/mt/f0
# /tmp/mt/f1 ← 0 和 1.5 天
到这一步就清楚了:+2 不是"两天前",是"满两天以上"。要删三天以前的日志,+2 是对的;要保留完整三天,得用 +3。我当初那个脚本删早了,就差这一层。
还有几个容易踩的地方。
-mmin 是按分钟算的,不做天级取整,-mmin -120 就是最近两小时内,这个比较直观。但它和 -mtime 不能混用同一个数字,-mtime 2 和 -mmin 2 差了三个数量级。
-daystart 会把比较基准从"现在"改成"今天零点"。这个在按自然日统计的时候有用,比如"昨天改过的文件":find . -daystart -mtime 1。不加的话算出来是滚动 24 小时,跨零点的时候结果会变。
如果实在不想记这些,-newermt 可以直接写时间点,语义清楚得多:
find /data/logs -name '*.log' ! -newermt '3 days ago' -delete
! -newermt '3 days ago' 就是"修改时间早于三天前"。我现在的清理脚本都换成这个写法了,隔几个月回来看也不用重新推一遍取整规则。
顺便说一句,-mtime 判断用的是 mtime,不是 ctime。chmod、chown 改的是 ctime,find -ctime 才看那个。之前排查一个"文件明明没动过却被清理了"的问题,最后发现是权限批量调整把 ctime 刷了,用 -ctime 一查全对上。
- 点赞
- 收藏
- 关注作者
评论(0)