快速寻找文件:locate命令
在Linux中最为常见的就是使用find去寻找文件,如果和xargs命令和管道,find一行命令能够发挥很大的作用,唯一的一个问题就是会很慢,尤其是从一个很深的目录层次下进行确认的时候,比如根目录/。而locate命令则从另外的角度提供了一种快速搜索文件的方法。
安装locate
以CentOS/RHEL为例,locate命令在最小化安装方式下不会被安装,需要手动进行安装,因为骑在mlocate包中,使用如下方式即可安装。
安装命令:yum install mlocate -y
安装示例如下所示:
[aaa@qq.com ~]# which locate
/usr/bin/which: no locate in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
[aaa@qq.com ~]# yum install mlocate -y
...省略
[aaa@qq.com ~]#
[aaa@qq.com ~]# which locate
/bin/locate
[aaa@qq.com ~]#
locate为什么快
有find了,为什么还需要locate。因为locate更快,初始化安装完毕之后直接执行locate ls,可以看到如下信息提示。
[aaa@qq.com ~]# locate ls
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[aaa@qq.com ~]#
提示找不到mlocate.db这个文件,实际上这就是locate命令快的原因,相较于find实时地确认文件的存在与否,locate则是到这样一个数据库里去查看。需要定期的进行状态的更新, 更新则使用如下命令即可。
更新数据库命令:updatedb
执行示例如下所示
[aaa@qq.com ~]# ls /var/lib/mlocate/
[aaa@qq.com ~]# which updatedb
/bin/updatedb
[aaa@qq.com ~]# updatedb
[aaa@qq.com ~]# ls /var/lib/mlocate/
mlocate.db
[aaa@qq.com ~]#
再次执行locate ls,可以看到所有文件名中包含ls的文件都被列出来了,其中也包含/usr/bin/ls命令。
[aaa@qq.com ~]# locate ls |wc -l
2435
[aaa@qq.com ~]# locate ls |head -n2
/boot/grub2/i386-pc/blscfg.mod
/boot/grub2/i386-pc/cbls.mod
[aaa@qq.com ~]# locate ls |grep -w bin |grep -w ls
/usr/bin/ls
/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/12/fs/bin/ls
/var/lib/rancher/k3s/agent/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/6/fs/bin/ls
/var/lib/rancher/k3s/data/2492a28b74abfbdbd3f943c8109a93e979669647bbbe95eadae43b60c667df69/bin/ls
[aaa@qq.com ~]#
如果是查询可执行文件,使用which不就好了么,但是which搜索的限制有2点,一是需要可执行,二是需要在PATH搜索路径中,大部分文件搜索的场景都不适合。
常用搜索技巧
技巧1:常用updatedb
为了避免新建的文件或则目录搜索不到,经常性的进行updatedb的执行,以保证所有的文件或者目录都在搜索的信息库中。
[aaa@qq.com ~]# mkdir testnewdirname
[aaa@qq.com ~]# locate testnewdirname
[aaa@qq.com ~]#
[aaa@qq.com ~]# updatedb
[aaa@qq.com ~]# locate testnewdirname
/root/testnewdirname
[aaa@qq.com ~]#
所以使用locate命令的缺点就看出来了,不能实时,updatedb也需要一定的时间来执行的,这是一个问题点。
技巧2: 支持通配符
可以使用通配符更好的返回搜索内容,比如
使用示例:搜索所有以yml结尾的文件
[aaa@qq.com ~]# locate -r 'yml$' |head -n2
/root/easypack/containers/alpine/jenkins/docker-compose.yml
/root/easypack/containers/alpine/jenkins/sample/master/docker-compose.yml
[aaa@qq.com ~]#
技巧3: 指定-i选项不区分大小写
比如搜索包含dockerfile字符的文件名称,可以看到文件命中包含Dockerfile的也被搜索了出来
[aaa@qq.com ~]# locate -i dockerfile |tail -n 3
/root/easypack/containers/standard/nexus/Dockerfile.3.19.1
/root/easypack/containers/standard/oracle/Dockerfile.11.2.0.xe
/root/easypack/containers/standard/rancher/Dockerfile
[aaa@qq.com ~]#
技巧4: 指定-n来显示结果数量
可以直接使用-n选项显示结果的行数,尤其在结果较多时显示前几项非常有效。
[aaa@qq.com ~]# locate -n 5 -r "\.sh$"
/boot/grub2/i386-pc/modinfo.sh
/etc/dhcp/dhclient-exit-hooks.d/azure-cloud.sh
/etc/dhcp/dhclient.d/chrony.sh
/etc/kernel/postinst.d/51-dracut-rescue-postinst.sh
/etc/profile.d/256term.sh
[aaa@qq.com ~]#
技巧5: 使用-e显示当前存在的文件或者目录
在没有使用updatedb进行信息同步更新时,可能会搜索出已经删除的文件或者临时文件,使用-e参数则可以避免这一问题的存在。比如如下使用示例:
[aaa@qq.com ~]# locate testnewdirname
/root/testnewdirname
[aaa@qq.com ~]# rm -rf testnewdirname/
[aaa@qq.com ~]# locate testnewdirname
/root/testnewdirname
[aaa@qq.com ~]# ls
anaconda-ks.cfg easypack
[aaa@qq.com ~]# pwd
/root
[aaa@qq.com ~]#
[aaa@qq.com ~]# locate -e testnewdirname
[aaa@qq.com ~]#
技巧6: 使用-d指定特定数据库
缺省时使用/var/lib/mlocate/mlocate.db文件,在特定需求下可以通过-d执行搜索对象数据库。
[aaa@qq.com ~]# locate testnewdirname
/root/testnewdirname
[aaa@qq.com ~]#
[aaa@qq.com ~]# cp /var/lib/mlocate/mlocate.db /tmp/mlocate.backup.db
[aaa@qq.com ~]# updatedb
[aaa@qq.com ~]# locate testnewdirname
[aaa@qq.com ~]#
[aaa@qq.com ~]# locate -d /tmp/mlocate.backup.db testnewdirname
/root/testnewdirname
[aaa@qq.com ~]#
总结
locate通过查询特定数据库中的信息可以快速获得文件的状况,在文件变化不太频繁时,并且数量有很大时还是有一定使用场景的。