前言:为什么每个运维都必须精通 find?
如果你问一个 Linux 老手「你最常用的命令是什么」,find 大概率排在前三。它不是 ls 那种「看一眼」的工具,而是真正的「搜索引擎」——按名称、大小、时间、权限、所有者、文件类型……几乎所有维度,它都能精准定位。
但现实中,很多人对 find 的使用停留在 find . -name "*.log" 这个层次。本文从 12 个真实生产场景出发,带你从入门到精通。
测试环境:Ubuntu 24.04 LTS,find 版本 4.9.0(GNU findutils)。所有示例可直接复制运行。
一、基础篇:find 的核心语法
$ find [路径] [表达式] [动作]
如果省略路径,默认从当前目录 . 开始。如果省略动作,默认执行 -print,即打印匹配的文件路径。
$ find /var/log -name "*.log"
/var/log/syslog
/var/log/auth.log
/var/log/kern.log
二、12 个生产环境实战场景
场景 1:按文件名查找
最常见的用法——在 /etc/nginx 下找所有 .conf 文件:
$ find /etc/nginx -name "*.conf"
/etc/nginx/nginx.conf
/etc/nginx/sites-available/default
/etc/nginx/conf.d/ssl.conf
如果需要忽略大小写,用 -iname:
$ find /var/log -iname "*.LOG"
场景 2:按文件类型查找
-type 是最实用的过滤条件之一:
| 选项 | 含义 |
|---|---|
f |
普通文件 |
d |
目录 |
l |
符号链接 |
s |
socket |
$ find /etc -type d -name "nginx"
/etc/nginx
找当前目录下所有空目录:
$ find . -type d -empty
场景 3:按文件大小查找
运维排障的救命稻草——磁盘满了,谁在吃空间?
$ find /var/log -type f -size +100M
/var/log/journal/d7b3.../system.journal
大小单位对照:
| 后缀 | 含义 | 示例 |
|---|---|---|
c |
字节 | -size +1024c |
k |
KB | -size +500k |
M |
MB | -size +100M |
G |
GB | -size +1G |
注意:
+100M是大于 100MB,-100M是小于 100MB,100M是精确 100MB(极少用到)。
场景 4:按修改时间查找
「昨天谁改了这个配置文件?」——-mtime 告诉你答案。
$ find /etc/nginx -name "*.conf" -mtime -1
/etc/nginx/sites-available/default
时间参数速查:
| 参数 | 含义 | 示例 |
|---|---|---|
-mtime -1 |
最近 24 小时内修改 | 排查谁动了配置 |
-mtime +7 |
7 天前修改 | 找旧日志/缓存 |
-mmin -30 |
最近 30 分钟内修改 | 实时监控 |
-atime +30 |
30 天内未访问 | 清理冷数据 |
-ctime -1 |
24h 内元数据变更 | 权限/所有者变化 |
清理 30 天前的临时文件:
$ find /tmp -type f -mtime +30 -delete
⚠️ 警告:
-delete不可逆!建议先用
场景 5:按权限查找
安全审计必备——找出权限过于宽松的文件:
$ find /var/www -type f -perm 777
$ find /etc -type f -perm /o+w 2>/dev/null
-perm /o+w 匹配任何「其他人可写」的文件,2>/dev/null 屏蔽权限不足的错误提示。
场景 6:按所有者查找
$ find /var/www -user www-data
$ find /home -group developers
找出不属于任何用户的孤儿文件:
$ find /srv -nouser
场景 7:多条件组合(AND / OR)
find 默认是 AND 逻辑,用 -o 实现 OR,用 ( ) 分组:
$ find /var/log \( -name "*.log" -o -name "*.gz" \) -mtime -1
等价于:找最近 1 天内修改的 .log 或 .gz 文件。
场景 8:对匹配文件执行操作(-exec)
这可能是 find 最强大的能力——找到文件后,立即对它做点什么。
批量修改权限:
$ find /var/www -type f -name "*.sh" -exec chmod +x {} \;
批量压缩旧日志:
$ find /var/log -type f -name "*.log" -mtime +30 -exec gzip {} \;
{} 是匹配文件名的占位符,\; 表示命令结束。如果想把多个文件一次性传给命令,用 + 替代 \;:
$ find /var/log -name "*.log" -exec du -sh {} +
场景 9:配合 xargs 处理海量文件
当匹配文件数量极大(数万、数十万),-exec 每次启动一个进程,效率低。xargs 批量处理:
$ find /data -type f -name "*.tmp" -print0 | xargs -0 rm -f
-print0 和 -0 配合,安全处理文件名中包含空格、换行等特殊字符的情况。
场景 10:按深度限制搜索范围
$ find / -maxdepth 3 -name "nginx.conf" 2>/dev/null
/etc/nginx/nginx.conf
/usr/share/doc/nginx-common/examples/nginx.conf
-maxdepth 限制向下搜索层数,-mindepth 限制起始层数:
$ find /var/log -mindepth 2 -type f
跳过 /var/log 本身,只搜子目录里的文件。
场景 11:排除指定目录
$ find / -path /proc -prune -o -path /sys -prune -o -name "*.conf" -print 2>/dev/null
-prune 排除指定路径,避免扫描 /proc、/sys 等虚拟文件系统。
场景 12:按 inode 查找与去重
找硬链接——两个文件名指向同一个 inode:
$ find /home -type f -links +1
按 inode 号查找(当你需要删除文件名包含奇怪字符的文件时):
$ ls -i # 先找到 inode 号
$ find . -inum 458752 -delete
三、find 与其他命令的黄金组合
find + grep:搜文件内容
$ find /etc/nginx -name "*.conf" -exec grep -l "proxy_pass" {} \;
在所有 nginx 配置文件中搜包含 proxy_pass 的。
find + stat:批量查看文件详情
$ find /var/log -name "*.log" -mtime -1 -exec stat --format="%n %s %y" {} \;
find + tar:打包指定时间范围的文件
$ find /var/log -name "*.log" -mtime -7 | tar -czf weekly_logs.tar.gz -T -
四、性能优化建议
- 指定具体路径:
find /var/log比find /快几百倍。 - 类型过滤放前面:
-type f -name "*.log"先筛掉目录,减少后续匹配量。 - 减少 -exec 调用次数:用
+替代\;,或用xargs。 - 合理使用 prune:排除不关心的目录,如
/proc、/sys、.git。 - 善用 maxdepth:不需要深层递归时设置
-maxdepth 3。
五、速查表
| 需求 | 命令 |
|---|---|
| 按名称找文件 | find /path -name "*.log" |
| 忽略大小写 | find /path -iname "*.LOG" |
| 找大文件(>100MB) | find /path -type f -size +100M |
| 找空文件/目录 | find /path -empty |
| 24h内修改的文件 | find /path -mtime -1 |
| 30天前的文件 | find /path -mtime +30 |
| 权限为777的文件 | find /path -perm 777 |
| 排除目录 | find / -path /proc -prune -o ... |
| 限制深度 | find /path -maxdepth 2 |
| 批量删除 | find /path -name "*.tmp" -delete |
| 批量执行命令 | find /path -name "*.sh" -exec chmod +x {} \; |
常见问题 FAQ
find 和 locate 有什么区别?什么时候用哪个?
locate 依赖预先构建的文件名数据库(updatedb),速度极快但结果可能过时(数据库通常每天更新一次)。find 实时扫描文件系统,结果精确但速度慢。简单规则:找文件名用 locate(毫秒级),需要按大小/时间/权限过滤用 find。
find -exec 中的 {} 和 \; 是什么意思?
{} 是匹配到的文件名占位符,每条匹配结果会替换到这里。\; 是命令结束标记(分号被转义,防止被 shell 解释)。如果想让多个匹配文件一次性传给命令(而不是每个文件启动一次进程),用 + 代替 \;。
如何安全地使用 find -delete?
-delete,用 -print 预览结果;② 把结果输出到文件,人工抽查;③ 确认无误后加上 -delete。或在最后确认前改用 -exec rm -i {} \; 逐个确认删除。另一个好习惯:先用 -maxdepth 限制范围测试。
延伸阅读: