Answers:
locate(1)
相对于find(1)
:速度只有一个大优势。
find(1)
虽然,有许多优于locate(1)
:
find(1)
是原始的,可以回溯到AT&T Unix的第一个版本。您甚至可以通过Busybox在缩减的嵌入式Linux中找到它。这几乎是普遍的。
locate(1)
比他小得多find(1)
。最早的祖先locate(1)
直到1983年才出现,locate
直到1994年被GNU findutils和4.4BSD所采用时,它才被广泛使用。
locate(1)
也是非标准的,因此默认情况下并非到处都安装它。某些POSIX类型的OS甚至没有提供它作为选项,并且在可用的情况下,实现可能缺少所需的功能,因为没有独立的标准指定必须可用的最小功能集。
有一个事实上的标准,是BSDlocate(1)
,但这只是因为其他两个主要的口味locate
履行所有选项:-0
,-c
,-d
,-i
,-l
,-m
,-s
,和-S
。mlocate
实现6个附加选项未在BSD locate
:-b
,-e
,-P
,-q
,--regex
和-w
。GNUlocate
实现这六个加上又是4:-A
,-D
,-E
,和-p
。(我忽略了别名和诸如-?
vs -h
vs的微小差异--help
。)
大多数Linux附带GNU locate
,但Red Hat Linux和Arch附带mlocate
。Debian既不在基本安装中也不安装,而是在其默认软件包存储库中提供了这两个版本。如果同时安装了两者,则将locate
运行“ ” mlocate
。
从 2014年12月发布的11.2开始,Oracle一直mlocate
在Solaris 中提供。在此之前,默认情况下未在Solaris上安装Oracle。(据推测,这样做是为了减少Solaris的与命令不兼容的Oracle的Linux,它是基于Red Hat Enterprise Linux的,它也使用。)locate
mlocate
IBM AIX仍然不出货的任何版本locate
,至少为AIX 7.2的,除非你安装GNU findutils
从AIX工具箱Linux应用程序。
较旧的“真实” Unix通常不包含的实现locate
。
find(1)
具有强大的表达式语法,具有许多功能,布尔运算符等。
find(1)
不仅可以通过名称选择文件。它可以选择:
按名称查找文件时,可以使用正则表达式在所有版本的GNU或BNU版本的文件中使用文件关联语法进行搜索。find(1)
当前版本的locate(1)
glob模式可以接受find
,但是BSD locate
根本不执行正则表达式。如果您和我一样,并且必须使用多种机器类型,那么您会发现自己更喜欢grep
过滤而不是依赖于-r
或--regex
。
locate
比起需要更强大的过滤功能find
是因为...
find(1)
不一定搜索整个文件系统。通常,您将其指向子目录,该子目录包含要对其进行操作的所有文件的父目录。实现的典型行为locate(1)
是弹出所有与您的模式匹配的文件,将其留给grep
过滤,以将其喷出缩小到最小。
(邪恶的提示:locate /
可能会为您提供系统上所有文件的列表!)
有locate(1)
like之类的变体,slocate(1)
它们根据用户权限限制输出,但这不是locate
任何主要操作系统中的默认版本。
find(1)
可以做的事情来的文件发现,除了刚找到他们。最强大和得到广泛支持的此类运算符是-exec
,但还有其他运算符。例如,在最新的GNU和BSD中找到实现,例如,您具有-delete
和-execdir
运算符。
find(1)
实时运行,因此其输出始终是最新的。
由于locate(1)
依赖数据库的更新时间为过去的几小时或几天,因此其输出可能已过时。(这是陈旧的缓存问题。)此硬币有两个方面:
locate
可以命名不再存在的文件。
GNU locate
并mlocate
带有-e
标记,使其在打印出过去发现的每个文件的名称之前先检查文件是否存在,但这会吃掉一些locate
速度优势,并且在BSD中不可用locate
。
locate
将无法命名自上次数据库更新以来创建的文件。
您将locate
知道对输出不信任,这可能是错误的。
有解决此问题的方法,但是我不知道有任何广泛使用的实现方式。例如,存在rlocate
,但它似乎不适用于任何现代Linux内核。
find(1)
没有比运行它的用户更多的特权。
因为locate
向系统上的所有用户提供了全局服务,所以它希望updatedb
运行其进程,root
以便可以看到整个文件系统。这导致选择安全性问题:
updatedb
以root身份运行,但使其输出文件对全世界可读,因此locate
可以在没有特殊特权的情况下运行。这样可以有效地向所有用户公开系统中所有文件的名称。这可能足以引起安全隐患,从而导致真正的问题。
locate
在Mac OS X和FreeBSD上以这种方式配置BSD 。
将数据库写为只能由读取root
,并使其具有locate
setuid
root权限,以便它可以读取数据库。这意味着必须locate
有效地重新实现操作系统的权限系统,以便它不会显示通常看不见的文件。它还会增加系统的攻击面,特别是冒着根升级攻击的风险。
创建一个特殊的locate
用户或组来拥有数据库文件,并将locate
二进制文件标记setuid/setgid
为该用户/组,以便它可以读取数据库。这本身并不能阻止特权升级攻击,但是可以极大地减轻一个人可能造成的损害。
mlocate
在Red Hat Enterprise Linux上以这种方式配置。
但是,您仍然遇到问题,因为如果可以在调试器上使用调试器locate
或导致调试器转储核心,则可以获取数据库的特权部分。
我没有找到一种创建真正的“安全” locate
命令的方法,缺少为系统上的每个用户分别运行该命令的方法,这抵消了它的许多优势find(1)
。
底线,两者都非常有用。locate(1)
当您尝试按名称查找特定文件(已知存在)时会更好,但是您根本不记得它的确切位置。find(1)
当您有重点的领域要检查时,或者需要它的许多优点时,它会更好。
find -- "$dir"
不健壮($dir
可能用作谓词),无法测试符号链接的属性,竞争条件问题……对我来说find
,要locate
解决两个不同的问题。在很多地方,使用find都不切实际(例如,包含数百万个文件的目录)。查找是一个仅限于文件名的索引系统。
locate
大致类似于find / -type f | gzip > locate.gz
,以及zgrep "$1" <locate.gz
locate
在findutils
软件包中,并且其updatedb
程序是根据来实现的find(1)
。因此,从这个意义上讲,locate(1)
实际上需要 find(1)
。:)
find
,locate
等在其他章节中,因此不必在那里在消除歧义的不同部分使用相同的名称在本手册(例如unlink(1)
vs unlink(2)
)中,我们那些习惯使用约定的人将其视为手册页参考。
find
如果没有仔细阅读手册页,Unix的新手或偶尔使用的用户就不可能成功使用。从历史上看,某些版本的find
甚至没有默认该-print
选项,这增加了用户的敌意。
locate
不太灵活,但在通常情况下使用起来更加直观。
find . -name 'nametosearch'
,或-iname
不区分大小写。替换.
为目录路径以搜索当前目录以外的目录。在那里,即使不涉及文件问题,也可以满足新手用户需求的90%。(我通常会使用find . -iname '*partialfilename*'
,如果从中进行搜索/
,我会使用find / -maxdepth 5 -iname '*partialname*'
它来缩短搜索时间,同时在90%的时间内找到我感兴趣的所有内容。在那里,有75%的中级用户需求。):)
locate的一个小缺点是它可能没有索引您感兴趣的文件系统的区域。在Debian桌面系统上,例如Linux Mint 17.2,/ etc / updatedb.conf文件配置为排除某些区域,包括/ tmp,/ var / spool和/home/.ecryptfs。
忽略/home/.ecryptfs可以防止将加密目录中的文件名暴露给未经授权的用户。但是,如果您的主目录已使用ecryptfs加密,则这也意味着您的主目录未建立索引,因此locate将在主目录中找不到任何内容。这可能会使它在很大程度上对您毫无用处(对我来说确实如此)。除了找不到结果之外,updatedb进程将定期加载磁盘而没有任何好处,如果您是系统的主要用户或唯一用户,则可能会被禁用。