[置顶] Linux 文件路径查询命令(find、locate、which、whereis)

时间:2022-06-19 09:22:06

一、find

根据『指定条件』 查询 『指定路径』下 的文件或目录,也可以进一步对查询结果『进行操作』, 具体使用参考man find,基本格式为 find [dirname] [options] [action] 具有几个主要特点:

  • 通配符查询
  • 支持正则表达式查询
  • 多条件查询 (与 、或、 非)
  • 按时间段查询
  • 默认递归查询,可指定递归深度
  • 实时查询硬盘,速度比较慢

常用场景

  • 查询目录 D 下的 A 文件
find D -name  A 
  • 搜索以D为根目录 下的所有 cpp 文件
find D -name "*.cpp"
  • 查询10 分钟内 D目录中 修改过的文件或目录
find . -mmin -10 
  • 查询 并 对每一个符合条件的文件执行操作
  • 查询 目录D 下 10分钟内被修改过的 cpp 文件
find . -mmin -10 -and -name '*.cpp'
  • 查询 用户 user 在 目录 D 下 10 分钟内修改过的cpp 文件
    find . -user user -and -mmin -10 -and -name '*.cpp'
  • 找出 用户 user 乱放在 目录 D 的文件 并删掉
find D -user user -exec rm {} \;
  • 查询D目录下文件名prefix开头的文件的路径 (正则表达式)
find D -regex '.*/prefix.*' 

二、Locate

通过man locate 得知该指令语义: 通过搜索本地数据库快速查询文件。
之所以快速是因为 建立了索引(find 是实时在硬盘上查找,因此查找速度比较慢),所谓 “本地数据库” 指的是 一个定期更新存储本机硬盘所有可访问的文件路径信息的数据库 定时的周期是多少? 一般默认为 每天更新一次。

  • locate 的数据库的路径? 答:可以通过 man locate查询, mac os 路径为: /var/db/locate.database
  • 如何手动更新locate 指令对应的数据库? 答:linux下执行 sudo updatedb, mac os 下没有 updatedb指令,只需要手动执行相应的update脚本,通过 man locate 可查询得知 对应的更新脚本路径:/usr/libexec/locate.updatedb , 因此只需执行:/usr/libexec/locate.updatedb #如遇权限问题请添加 sudo

  • 如何更改更新的频率? 答:手动设置cron定时任务 定时更新即可, 如果希望每天每 8 个小时更新一次, crontab -e 设置:

* */8 * * * /usr/libexec/locate.updatedb;

注:crontab 定时任务的语法格式为

第1列分钟1~59
第2列小时1~23(0表示子夜)
第3列日1~31
第4列月1~12
第5列星期0~6(0表示星期天)
第6列要运行的命令

常用场景

  • 普通查询
locate pwd; # 搜索包含给定字符串的文件路径
  • 使用通配符
locate p?d; # 即使遇到 pXd 也会被匹配
  • 正则查询 (注:mac os 的locate 不支持 正则查询)
locate -r  ".*/pwd$" # 匹配文件名为pwd的路径
  • 因为是定期更新, 数据库的文件路径信息可能迟滞,可能短时间内增删的文件不会被搜索到, 此时可以更新locate database
# Linux
updatedb #如遇权限问题请添加 sudo

# Mac Os 版
/usr/libexec/locate.updatedb #如遇权限问题请添加 sudo

三、which

根据阮一峰老师的讲解:

which命令的作用是,在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。

由此可得出which 命令的几个特点:

  • 查询可执行程序或命令 (不会查询其他文件)
  • 只查询 环境变量$PATH指代的目录列表
  • 只返回首个搜索结果
which  cd;  // cd: shell built-in command
which php; // /usr/bin/php

注:有时一些命令 通过which会查不到结果,有两种可能:

  • 命令所在目录 不包含于 $PATH 环境变量
  • 命令可能是内置命令 (可以通过 type 命令 确认)
# cd 命令居然查询不到
[root@115 ~] $ which cd
/usr/bin/which: no cd in (/usr/java/jdk1.7.0_51/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/jun/gocode/bin:/root/bin)
# 哦,是内置命令,忘了~
[root@115 ~] $ type cd
cd is a shell builtin

四、whereis

根据 man whereis 对该命令的定义: whereis - locate the binary, source, and manual page files for a command,可知,该指令只查询命令二进制文件manual 说明文件源文件 ,可以分别通过 -b,-m和-s 指定只显示特定类型的文件路径

[root@115 ~] $ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz # 二进制文件和manual文件的相关路径
[root@115 ~] $ whereis -b ls
ls: /bin/ls # 指定返回二进制文件的路径
[root@115 ~] $ whereis -m ls
ls: /usr/share/man/man1/ls.1.gz # 指定返回manual文件
[root@115 ~] $ whereis -s ls
ls: # 搜索不到源代码文件

so , whereis 命令是搜哪里文件的?

whereis then attempts to locate the desired program in a list of standard Linux places.

五、FAQ

  • which 与 whereis 的异同:都是对可指令或程序的查询;which依据$PATH查询,而whereis依据linux标准目录; which仅返回第一个匹配的结果, whereis在默认情况下可能返回(二进制文件、manual文件和源文件);
  • locate 和 find 的区别:locate 数据实时性不如find; locate建立了索引, 查询效率高;find 功能更为强大: locate仅能根据路径名称进行查询(支持正则和通配),find 同时还支持 时间,权限等不同维度 和多条件查询,etc。

  • find 命令 pathname,wholename 以及 name 选项的差别

相关参考

  1. Linux的五个查找命令 阮一峰老师:http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html
  2. 每天一个linux命令(18):locate 命令:http://www.cnblogs.com/peida/archive/2012/11/12/2765750.html
  3. * —— The differences between which and whereis:http://superuser.com/questions/40301/which-whereis-differences