find 命令默认递归、打印且不报错,但易因时间参数误用(如 -mtime 按24小时整段而非自然日)、引号缺失导致通配符被shell提前展开、未限制跨文件系统或符号链接等引发误删、漏查或卡死;应优先用 -daystart、-mmin、-xdev、-L、-maxdepth 等选项增强准确性和安全性。

直接说结论:find 不是“搜一下就行”的简单命令,它默认递归、默认打印、默认不报错,但一写错时间参数或漏掉引号,就可能删错文件、漏掉结果、甚至卡死在挂载点上。
为什么 -mtime -7 找不到昨天改的文件?
因为 -mtime 是按“24 小时整段”计算的,不是自然日。比如现在是 2026-06-12 00:40,-mtime -7 实际查的是 2026-06-05 00:40 之后修改的文件——你昨天(6月11日)下午改的文件,只要在 00:40 之前改的,就不算在内。
- 要用自然日范围,加
-daystart:例如find . -daystart -mtime -1表示“从今天 00:00 开始算起的 24 小时内” -
-mmin -60比-mtime更准,适合查最近一小时改的文件 - 注意:+n / -n / n 的含义容易反——
+7是“7 天前更早”,-7是“7 天内”,7是“正好第 7 天那天”(即 168±24 小时前)
-name 通配符不生效?先检查引号和大小写
常见错误是写成 find . -name *.log —— shell 会先展开 *.log 成当前目录下匹配的文件名,再传给 find,导致查的不是子目录,而是只在当前层找几个已存在的名字。
- 必须用单引号或双引号包裹模式:
find . -name "*.log" -
-name区分大小写;要忽略大小写,换-iname:find . -iname "readme.*" - 想匹配路径中含
/bin/的文件,不能用-name,得用-path:find /usr -path "*/bin/*" - 复杂模式建议用
-regex,但注意正则类型默认是 emacs,加-regextype posix-extended才支持(jpg|png)
删文件前一定要先 -print 或 -ls 看一眼
-delete 动作没有确认机制,一旦条件写宽了(比如漏了 -type f),可能把目录甚至整个 /tmp 下的子目录都删掉。
- 安全做法是分两步:先确认结果,再执行删除
find /var/log -name "*.old" -mtime +90 -print
确认无误后,再换成:find /var/log -name "*.old" -mtime +90 -delete - 想看详细信息(大小、权限、时间),用
-ls:find . -size +100M -ls - 要用
-exec做更复杂操作时,注意语法:{} \;中的空格和反斜杠缺一不可,否则报错find: missing argument to '-exec'
跨文件系统或符号链接时,默认行为很危险
默认情况下,find / 会钻进所有挂载点(比如 /proc、/sys、/mnt/nas),轻则慢,重则卡死或报错 Permission denied。
- 加
-xdev(或-mount)禁止跨文件系统:find / -xdev -name "core" 2>/dev/null - 符号链接默认不跟随,如果目标在链接指向的位置,需加
-L:find -L /opt -name "java" - 深度太深浪费资源?用
-maxdepth 2限制层级,避免扫完整个/home -
-empty只匹配空文件或空目录,但注意:空目录若含隐藏文件(如.gitignore),就不是空的
最常被忽略的一点:所有时间类参数(-mtime、-atime、-ctime)都依赖系统时钟和文件系统本身的 time 字段精度,某些网络文件系统(NFS、CIFS)或容器环境里,这些字段可能不准或被禁用——此时 -mmin 或 -newer 更可靠。


















