
本机造了七个文件,修改时间从 1 小时前排到 73 小时前,跨了三天。想捞出「一天以上没动过的」,写成 find . -name 'f-*' -mtime +1,结果只返回 2 个,24 小时到 48 小时之间的那两个一个都没进结果。顺序和数量都在下面这张表里。
== 每个文件的实际年龄(小时)==
f-01h 1 小时前 修改时间 2026-09-25 07:06
f-06h 6 小时前 修改时间 2026-09-25 02:06
f-23h 23 小时前 修改时间 2026-09-24 09:06
f-25h 25 小时前 修改时间 2026-09-24 07:06
f-47h 47 小时前 修改时间 2026-09-23 09:06
f-49h 49 小时前 修改时间 2026-09-23 07:06
f-73h 73 小时前 修改时间 2026-09-22 07:06
年龄是刻意挑在 24 小时和 48 小时两边的:23 小时、25 小时、47 小时、49 小时各一个,用来测边界到底切在哪儿。
八条谓词各捞出哪些
== 每条谓词各命中哪些文件 ==
-mtime -0 命中 0 个 :
-mtime 0 命中 3 个 : f-01h f-06h f-23h
-mtime -1 命中 3 个 : f-01h f-06h f-23h
-mtime 1 命中 2 个 : f-25h f-47h
-mtime +0 命中 4 个 : f-25h f-47h f-49h f-73h
-mtime +1 命中 2 个 : f-49h f-73h
-mmin -1440 命中 3 个 : f-01h f-06h f-23h
-mmin +1440 命中 4 个 : f-25h f-47h f-49h f-73h
同一批文件,八条谓词分出五种结果。-mtime 0 和 -mtime -1 都捞出 3 个,-mtime -0 一个都不捞。-mtime +1 是 2 个,-mtime +0 是 4 个,差的那两个正是 25 小时和 47 小时。-mmin -1440 与 -mtime -1 相同,-mmin +1440 与 -mtime +0 相同。
换成年龄区间看更直观:-mtime -1 和 -mtime 0 覆盖 0 到 24 小时,-mtime 1 覆盖 24 到 48 小时,-mtime +0 是 24 小时往上不封顶,-mtime +1 从 48 小时起算。八条谓词实际只落在四个区间里,而「24 小时以上」这一档只有 -mtime +0 和 -mmin +1440 能表达到。按这个样本算,用 -mtime +1 去筛 24 小时以上的文件,命中 2 个,该命中 4 个,覆盖率正好一半。
判据是整数个周期,不是多久以前
-mtime n 拿到的不是一个时长,是年龄里包含几个完整的 24 小时周期,也就是 年龄 ÷ 86400 取整。判断再拿这个整数去比 n。
-1 表示周期数小于 1,等于年龄不满 24 小时,23 小时的进、25 小时的出。+1 表示周期数大于 1,也就是年龄至少 48 小时,25 小时和 47 小时都落在「第 1 个完整周期」里,两条都不匹配,漏掉的根源就在这里。想表达「超过一天」,-mtime +0 才对,它和 -mmin +1440 结果一致。
-mtime -0 捞不到东西是因为「周期数小于 0」永远不成立,-mtime 0 才是「不足一个完整周期」这一档。这两个写法只差一个符号,一个是空结果,一个是最近一天内的全部文件。
周期起点跟着当前时刻往前移,所以同一条命令在早上跑和晚上跑,落在边界附近的文件会换档。cron 里写的清理任务,命中集合因此随运行时刻变化,这一点在排查「昨天怎么没清掉」的时候要先想到。GNU find 另有一条 -daystart 把周期起点改成当天零点,本机这版 BSD find 没有这条谓词,实测直接报 unknown primary,用得到它的话得换到 GNU 环境再验。
要精确到时刻就换 -newermt
== 精确到时刻的窗口(macOS 的 -newermt)==
-newermt -v-24H 起点 2026-09-24 08:06:48 命中 3 个 : f-01h f-06h f-23h
-newermt -v-48H 起点 2026-09-23 08:06:48 命中 5 个 : f-01h f-06h f-23h f-25h f-47h
-newermt -v-2d 起点 2026-09-23 08:06:48 命中 5 个 : f-01h f-06h f-23h f-25h f-47h
-newermt 直接接一个时间点,比当前时刻新就匹配。macOS 上用 date -v-24H 造出「24 小时之前」那个时刻,48 小时和 2 天两种写法给出同一个起点、同一批结果。这条谓词的含义是明确的时长,不用换算周期数。
== 本机环境 ==
系统: macOS 26.2,BSD find
-mtime 的周期起点是「现在」往前数的整数个 24 小时
该写哪一条
需要「最近 24 小时」这种说法,写 -mmin -1440 或者 -newermt,谓词和读法对得上。需要按天粗筛,写 -mtime +0 表示至少一天、-mtime +1 表示至少两天,落笔之前把周期数换算成实际年龄。
要按自然日切分,比如「本月 1 号之后的日志」,-newermt '2026-09-01 00:00:00' 这种绝对时间点比周期数直观,脚本里也能直接从变量拼出来,不用关心运行时刻落在哪儿。
清理脚本里我不用 -mtime +N 这套写法,全部按 -mmin 写,省掉每次换算时的一次停顿。
只按 -mmin 写还有个附带好处:谓词里的数字就是分钟数,换个说法比如「三天前」,把 4320 填进去就完事,不用再想清楚这该写成 +2 还是 +3。
漏掉的后果通常是双份的:上一轮该清没清的文件留在盘上,下一轮再按同样的条件筛,两次都放过它。等到磁盘告警才回头查脚本,边界错在哪儿得重新造一批文件才能对上。