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