定位与查找:用法,彼此的优缺点


Answers:


166

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 findutils4.4BSD所采用时,它才被广泛使用。

  • locate(1)也是非标准的,因此默认情况下并非到处都安装它。某些POSIX类型的OS甚至没有提供它作为选项,并且在可用的情况下,实现可能缺少所需的功能,因为没有独立的标准指定必须可用的最小功能集。

    有一个事实上的标准,是BSDlocate(1),但这只是因为其他两个主要的口味locate履行所有选项:-0-c-d-i-l-m-s,和-Smlocate实现6个附加选项未在BSD locate-b-e-P-q--regex-wGNUlocate实现这六个加上又是4-A-D-E,和-p。(我忽略了别名和诸如-?vs -hvs的微小差异--help。)

    BSD和Mac OS X 附带了 BSD locate

    大多数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的,它也使用。)locatemlocate

    IBM AIX仍然不出货的任何版本locate至少为AIX 7.2的,除非你安装GNU findutilsAIX工具箱Linux应用程序

    HP-UX显得缺乏locate基本系统。

    较旧的“真实” 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)依赖数据库的更新时间为过去的几小时或几天,因此其输出可能已过时。(这是陈旧的缓存问题。)此硬币有两个方面:

    1. locate 可以命名不再存在的文件。

      GNU locatemlocate带有-e标记,使其在打印出过去发现的每个文件的名称之前先检查文件是否存在,但这会吃掉一些locate速度优势,并且在BSD中不可用locate

    2. locate 将无法命名自上次数据库更新以来创建的文件。

    您将locate知道对输出不信任,这可能是错误的。

    有解决此问题的方法,但是我不知道有任何广泛使用的实现方式。例如,存在rlocate,但它似乎不适用于任何现代Linux内核。

  • find(1) 没有比运行它的用户更多的特权。

    因为locate向系统上的所有用户提供了全局服务,所以它希望updatedb运行其进程,root以便可以看到整个文件系统。这导致选择安全性问题:

    1. updatedb以root身份运行,但使其输出文件对全世界可读,因此locate可以在没有特殊特权的情况下运行。这样可以有效地向所有用户公开系统中所有文件的名称。这可能足以引起安全隐患,从而导致真正的问题。

      locate在Mac OS X和FreeBSD上以这种方式配置BSD 。

    2. 将数据库写为只能由读取root,并使其具有locate setuidroot权限,以便它可以读取数据库。这意味着必须locate有效地重新实现操作系统的权限系统,以便它不会显示通常看不见的文件。它还会增加系统的攻击面,特别是冒着根升级攻击的风险。

    3. 创建一个特殊的locate用户或组来拥有数据库文件,并将locate二进制文件标记setuid/setgid为该用户/组,以便它可以读取数据库。这本身并不能阻止特权升级攻击,但是可以极大地减轻一个人可能造成的损害。

      mlocateRed Hat Enterprise Linux上以这种方式配置。

      但是,您仍然遇到问题,因为如果可以在调试器上使用调试器locate或导致调试器转储核心,则可以获取数据库的特权部分。

    我没有找到一种创建真正的“安全” locate命令的方法,缺少为系统上的每个用户分别运行该命令的方法,这抵消了它的许多优势find(1)

底线,两者都非常有用。locate(1)当您尝试按名称查找特定文件(已知存在)时会更好,但是您根本不记得它的确切位置。find(1)当您有重点的领域要检查时,或者需要它的许多优点时,它会更好。


抱歉,我忽略了“ slocate”段。rlocate解决了过时的缓存问题。您可能要提到一些find的怪癖,例如find -- "$dir" 不健壮($dir可能用作谓词),无法测试符号链接的属性,竞争条件问题……对我来说find,要locate解决两个不同的问题。在很多地方,使用find都不切实际(例如,包含数百万个文件的目录)。查找是一个仅限于文件名的索引系统。
2013年

2
的第一个实现locate大致类似于find / -type f | gzip > locate.gz,以及zgrep "$1" <locate.gz
F. Hauri

@ F.Hauri:有趣的琐事。还有更多信息:GNU locatefindutils软件包中,并且其updatedb程序是根据来实现的find(1)。因此,从这个意义上讲,locate(1)实际上需要 find(1)。:)
沃伦·扬

1
@WarrenYoung为什么对foo(1)而不是foo进行常量引用?foo是否有其他不同的版本?
关于natty的坚果,2013年

4
@nuttyaboutnatty:这是在Unix的手册一个古老的惯例,这意味着手册第1虽然这是事实,没有findlocate等在其他章节中,因此不必在那里在消除歧义的不同部分使用相同的名称在本手册(例如unlink(1)vs unlink(2))中,我们那些习惯使用约定的人将其视为手册页参考。
沃伦·杨

35

locate使用预建数据库,该数据库应定期更新,同时find在文件系统上进行迭代以查找文件。

因此,locate它的速度比快得多find,但是如果数据库(可以看作是缓存)未更新(请参阅updatedb命令),则可能不准确。

此外,find还可以提供更细的粒度,因为您可以locate使用文件名匹配的模式来按文件的每个属性过滤文件。


7

find如果没有仔细阅读手册页,Unix的新手或偶尔使用的用户就不可能成功使用。从历史上看,某些版本的find甚至没有默认该-print选项,这增加了用户的敌意。

locate 不太灵活,但在通常情况下使用起来更加直观。


1
另一方面,locate必须维护一个数据库并定期运行,因此我已在驻留在我们专用网络上的所有Linux服务器上禁用了它。
Rui F Ribeiro 2015年

2
这有什么难的? find . -name 'nametosearch',或-iname不区分大小写。替换.为目录路径以搜索当前目录以外的目录。在那里,即使不涉及文件问题,也可以满足新手用户需求的90%。(我通常会使用find . -iname '*partialfilename*',如果从中进行搜索/,我会使用find / -maxdepth 5 -iname '*partialname*'它来缩短搜索时间,同时在90%的时间内找到我感兴趣的所有内容。在那里,有75%的中级用户需求。):)
通配符

2

locate的一个小缺点是它可能没有索引您感兴趣的文件系统的区域。在Debian桌面系统上,例如Linux Mint 17.2,/ etc / updatedb.conf文件配置为排除某些区域,包括/ tmp,/ var / spool和/home/.ecryptfs。

忽略/home/.ecryptfs可以防止将加密目录中的文件名暴露给未经授权的用户。但是,如果您的主目录已使用ecryptfs加密,则这也意味着您的主目录未建立索引,因此locate将在主目录中找不到任何内容。这可能会使它在很大程度上对您毫无用处(对我来说确实如此)。除了找不到结果之外,updatedb进程将定期加载磁盘而没有任何好处,如果您是系统的主要用户或唯一用户,则可能会被禁用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.