Linux查找文件命令:find、locate、which、whereis实战

开篇:

"那个 nginx.conf 到底在哪?"------这是每个 Linux 新手和老手都会遇到的灵魂拷问。

有一次我接手一台"祖传"服务器,前同事把 Nginx 装在了编译目录里,配置文件既不在 /etc/nginx 也不在 /usr/local/nginx/conf。我用了三招定位:

bash 复制代码
which nginx            # 找到可执行文件在哪个目录
find / -name "nginx.conf" 2>/dev/null   # 全盘找配置文件

三分钟内就锁定了目标。查找文件,是 Linux 运维和开发的高频刚需 。今天我们把 findlocatewhichwhereis 四个查找命令一次讲透,并说清它们各自适合什么场景。

一、四个命令的定位:一张表先建立全局观

命令 查找对象 查找依据 速度 适用场景
find 任意文件/目录 实时扫描目录树,按名字/类型/大小/时间等条件 慢(但功能最强) 精确、复杂条件查找
locate 文件名 查询预建数据库(updatedb) 极快 模糊记得名字的快速查找
which 可执行命令 搜索 PATH 环境变量 极快 命令装在哪个目录、是否已安装
whereis 可执行命令及其文档 搜索标准目录 + PATH 同时找二进制、源码、man 手册

一句话记忆:which/whereis 找命令,locate 快速找文件,find 精确找一切

二、find:功能最强的"搜索机器"

语法格式

bash 复制代码
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

常用动作

动作 说明
-print 打印路径(默认动作)
-exec 命令 {} \; 对每个结果执行命令,{} 是结果占位符
-delete 直接删除匹配的文件
-ls ls -l 格式列出详细信息

实战示例与预期输出

示例 1:按名字和类型查找

bash 复制代码
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 天前修改的大日志文件

bash 复制代码
find /var/log -name "*.log" -mtime +7 -size +100M -ls

这条命令把"超过 7 天没动过、且大于 100MB 的日志"列出来,配合第 92 篇的 logrotate 思路,就是清理磁盘的第一步。

示例 3:对结果批量执行命令------删除临时文件

bash 复制代码
find /tmp -name "*.tmp" -type f -exec rm -f {} \;

这里 {} 逐个替换为找到的文件路径,\; 表示 -exec 命令结束(注意分号前有反斜杠)。

示例 4:统计某目录下普通文件数量

bash 复制代码
find /var/log -type f | wc -l

预期输出(示例值):

复制代码
128

⚠️ 常见错误与注意事项

  1. -name 的通配符必须加引号 :写成 find / -name *.log 时,Shell 会在 find 执行前先把 *.log 展开,往往匹配不到或匹配错误。正确写法是 -name "*.log"
  2. 权限报错刷屏find / -name x 会遍历整个系统,遇到无权访问的目录会刷出一堆 Permission denied。加 2>/dev/null 屏蔽错误输出。
  3. -delete 慎用 :它删除后不可恢复,务必先 -print 预览再删。
  4. -exec 别忘 {}\; :格式写错会报 find: missing argument to -exec

三、locate:数据库加持的"秒查"

locate 的查找速度是"秒回",因为它不扫描磁盘,而是查询一个预先建好的文件名数据库

语法格式

bash 复制代码
locate [选项] 关键词

常用参数

参数 说明
-i 忽略大小写
-c 只输出匹配数量
-r 正则 用正则匹配
-n 数字 只显示前 N 条

示例与预期输出

示例:找名字里带 docker 的文件

bash 复制代码
locate docker | head -10

预期输出(节选):

复制代码
/etc/apparmor.d/docker
/etc/bash_completion.d/docker
/usr/bin/docker
/usr/share/man/man1/docker.1.gz

⚠️ 注意事项

数据库不会实时更新。刚创建的文件 locate 可能找不到,需要先更新数据库:

bash 复制代码
sudo updatedb    # Ubuntu/Debian

CentOS/Rocky 使用 yum install mlocate 安装后同样有 updatedb。另外有些发行版默认不装 locate(如新版 Ubuntu 用 plocate),装一下即可。

常见错误:以为 locate 找不到就说明文件不存在------它可能只是数据库过期了。

四、which:命令"藏"在哪个目录

which 沿着 PATH 环境变量里的目录逐个查找,返回可执行命令的完整路径。

语法格式

bash 复制代码
which [选项] 命令名

常用参数

参数 说明
-a 显示所有匹配路径(PATH 中可能有多个同名)
-i 忽略大小写(GNU 版本)

示例与预期输出

示例:查 python3 在哪、是否已安装

bash 复制代码
which python3

预期输出:

复制代码
/usr/bin/python3

如果没安装则无输出(退出码为 1)。因此 which 常被写进脚本做依赖检查:

bash 复制代码
which git || { echo "git 未安装"; exit 1; }

小知识:which 只看 PATH,如果某个命令是通过完整路径调用(如 /opt/app/bin/tool),which tool 是找不到的,用 type -a toolfind 兜底。

五、whereis:连源码和文档一起找

whereiswhich 更进一步,它会去标准目录搜索,同时返回二进制、源码和 man 手册的位置。

语法格式

bash 复制代码
whereis [选项] 命令名

常用参数

参数 说明
-b 只找二进制文件
-m 只找 man 手册
-s 只找源码

示例与预期输出

示例:查 nginx 的所有相关文件

bash 复制代码
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 都能批量处理结果,区别在哪?

对比项 -exec ... \; 管道 + xargs
执行方式 每个文件起一个子进程 批量打包成参数,一次执行多次
处理特殊文件名 安全(逐项传参) 需加 -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。

相关推荐
j7~1 小时前
【Linux网络加餐】(篇七)网络版计算器(中):协议落地、报文分隔与完整链路
linux·c++·网络编程·tcp·报文分割·网络计算器·协议落地
团子股股东峥哥1 小时前
day39-RHEL-访问网络附加存储
linux·运维·服务器
不会写代码的小可爱&&1 小时前
深入 Linux 内核内存管理:slab/slub 分配器原理剖析
linux·硬件架构
名字还没想好☜1 小时前
Kubernetes 用 kubectl port-forward 和 proxy 调试集群内服务:两者区别、断连自动重连与为什么别用在生产
运维·docker·kubernetes
H_oRIZoN_2 小时前
Linux入门DAY44 ARM 入门 Day02|ARM 汇编指令、模式切换、栈操作、汇编 C 混合编程
linux·单片机·嵌入式硬件·arm·linux应用编程
程序员-Benothing3 小时前
Linux文件查看与编辑:cat、less、tail、vim快速入门
linux·运维·服务器
考虑考虑9 小时前
docker compose V2版本新属性
运维·后端·自动化运维
AlanBruce10 小时前
摩尔信使MThings功能综述与应用使用指南
linux·自动化·plc·mthings·摩尔信使
小小的木头人10 小时前
Ubuntu Samba修改端口绕过445封禁挂载
运维·ubuntu