开篇:
“那个 nginx.conf 到底在哪?”——这是每个 Linux 新手和老手都会遇到的灵魂拷问。
有一次我接手一台"祖传"服务器,前同事把 Nginx 装在了编译目录里,配置文件既不在 /etc/nginx 也不在 /usr/local/nginx/conf。我用了三招定位:
which nginx # 找到可执行文件在哪个目录
find / -name "nginx.conf" 2>/dev/null # 全盘找配置文件
三分钟内就锁定了目标。查找文件,是 Linux 运维和开发的高频刚需。今天我们把 find、locate、which、whereis 四个查找命令一次讲透,并说清它们各自适合什么场景。
一、四个命令的定位:一张表先建立全局观
| find | 任意文件/目录 | 实时扫描目录树,按名字/类型/大小/时间等条件 | 慢(但功能最强) | 精确、复杂条件查找 |
| locate | 文件名 | 查询预建数据库(updatedb) | 极快 | 模糊记得名字的快速查找 |
| which | 可执行命令 | 搜索 PATH 环境变量 | 极快 | 命令装在哪个目录、是否已安装 |
| whereis | 可执行命令及其文档 | 搜索标准目录 + PATH | 快 | 同时找二进制、源码、man 手册 |
一句话记忆:which/whereis 找命令,locate 快速找文件,find 精确找一切。
二、find:功能最强的"搜索机器"
语法格式
find [起始路径] [匹配条件] [动作]
起始路径不写默认是当前目录 .。find 会递归遍历目录树,逐项匹配条件,最后执行动作(默认动作是打印路径)。
常用匹配条件
| -name "模式" | 按文件名(支持通配符,需加引号) | -name "*.log" |
| -iname "模式" | 忽略大小写的文件名 | -iname "Readme*" |
| -type f/d/l | 按类型:文件/目录/符号链接 | -type f |
| -size +100M | 按大小(+ 大于、- 小于) | -size +1G |
| -mtime +7 | 按修改时间:7 天前(+7)/7 天内(-7) | -mtime -1 |
| -user 用户名 | 按属主 | -user www-data |
| -perm 644 | 按权限 | -perm -4000(找 SUID) |
| -maxdepth N | 限制递归深度 | -maxdepth 2 |
| -empty | 空文件/空目录 | -empty |
常用动作
| 打印路径(默认动作) | |
| -exec 命令 {} \\; | 对每个结果执行命令,{} 是结果占位符 |
| -delete | 直接删除匹配的文件 |
| -ls | 以 ls -l 格式列出详细信息 |
实战示例与预期输出
示例 1:按名字和类型查找
find /etc -name "*.conf" -type f | head -5
预期输出:
/etc/rsyslog.conf
/etc/adduser.conf
/etc/deluser.conf
/etc/logrotate.conf
/etc/ucf.conf
示例 2:找出 7 天前修改的大日志文件
find /var/log -name "*.log" -mtime +7 -size +100M -ls
这条命令把"超过 7 天没动过、且大于 100MB 的日志"列出来,配合第 92 篇的 logrotate 思路,就是清理磁盘的第一步。
示例 3:对结果批量执行命令——删除临时文件
find /tmp -name "*.tmp" -type f -exec rm -f {} \\;
这里 {} 逐个替换为找到的文件路径,\\; 表示 -exec 命令结束(注意分号前有反斜杠)。
示例 4:统计某目录下普通文件数量
find /var/log -type f | wc -l
预期输出(示例值):
128
⚠️ 常见错误与注意事项
三、locate:数据库加持的"秒查"
locate 的查找速度是"秒回",因为它不扫描磁盘,而是查询一个预先建好的文件名数据库。
语法格式
locate [选项] 关键词
常用参数
| -i | 忽略大小写 |
| -c | 只输出匹配数量 |
| -r 正则 | 用正则匹配 |
| -n 数字 | 只显示前 N 条 |
示例与预期输出
示例:找名字里带 docker 的文件
locate docker | head -10
预期输出(节选):
/etc/apparmor.d/docker
/etc/bash_completion.d/docker
/usr/bin/docker
/usr/share/man/man1/docker.1.gz
⚠️ 注意事项
数据库不会实时更新。刚创建的文件 locate 可能找不到,需要先更新数据库:
sudo updatedb # Ubuntu/Debian
CentOS/Rocky 使用 yum install mlocate 安装后同样有 updatedb。另外有些发行版默认不装 locate(如新版 Ubuntu 用 plocate),装一下即可。
常见错误:以为 locate 找不到就说明文件不存在——它可能只是数据库过期了。
四、which:命令"藏"在哪个目录
which 沿着 PATH 环境变量里的目录逐个查找,返回可执行命令的完整路径。
语法格式
which [选项] 命令名
常用参数
| -a | 显示所有匹配路径(PATH 中可能有多个同名) |
| -i | 忽略大小写(GNU 版本) |
示例与预期输出
示例:查 python3 在哪、是否已安装
which python3
预期输出:
/usr/bin/python3
如果没安装则无输出(退出码为 1)。因此 which 常被写进脚本做依赖检查:
which git || { echo "git 未安装"; exit 1; }
小知识:which 只看 PATH,如果某个命令是通过完整路径调用(如 /opt/app/bin/tool),which tool 是找不到的,用 type -a tool 或 find 兜底。
五、whereis:连源码和文档一起找
whereis 比 which 更进一步,它会去标准目录搜索,同时返回二进制、源码和 man 手册的位置。
语法格式
whereis [选项] 命令名
常用参数
| -b | 只找二进制文件 |
| -m | 只找 man 手册 |
| -s | 只找源码 |
示例与预期输出
示例:查 nginx 的所有相关文件
whereis nginx
预期输出:
nginx: /usr/sbin/nginx /usr/share/man/man8/nginx.8.gz
如果你想看某个命令的手册位置,whereis -m ls 就能给出 /usr/share/man/man1/ls.1.gz。
六、知识扩展:find 的 -exec 与管道 xargs 的取舍
find -exec rm -f {} \\; 和 find … | xargs rm -f 都能批量处理结果,区别在哪?
| 执行方式 | 每个文件起一个子进程 | 批量打包成参数,一次执行多次 |
| 处理特殊文件名 | 安全(逐项传参) | 需加 -print0 + -0 配合,否则空格/换行文件名会出错 |
| 速度 | 慢(进程开销大) | 快 |
推荐做法:文件名简单时用 xargs(配合 -print0 更稳),追求稳妥或文件少时用 -exec。关于 xargs 的深入用法(-n、-I、-P 并行),第 19 篇专门展开。
另一个知识点:find 的条件默认是 AND(与),比如 -name "*.conf" -type f 表示两个条件同时满足。如果要表达 OR,用 -o 并配合括号:find /etc \\( -name "*.conf" -o -name "*.ini" \\)。注意括号要转义或加引号,否则 Shell 会把它当子 shell。
网硕互联帮助中心







评论前必须登录!
注册