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

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

在Linux和Unix系统中,有两种常见的搜索命令:locatefind

各自的优点和缺点是什么?什么时候一个人比另一个人有优势?

答案1

locate(1)与此相比,只有一大优势find(1):速度。

find(1),不过,有许多优点locate(1)

  • find(1)是原始的,回到 AT&T Unix 的第一个版本。您甚至可以在精简版嵌入式 Linux 中找到它通过Busybox。这几乎是普遍的。

    locate(1)比 年轻得多find(1)。最早的祖先是locate(1) 直到1983年才出现,直到 1994 年才被广泛使用locate,当时它被采用进入 GNU findutils进入4.4BSD

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

    有一个事实上的标准,是BSDlocate(1),但这只是因为其他两种主要风格locate实现了它的所有选项:-0-c-d-i-l-m-s-Smlocate实现了 BSD 中没有的 6 个附加选项locate-b, -e, -P, -q,--regex-w实现了 BSD 中没有的GNUlocate实现这六个加上另一个-A-D-E, 和-p。 (我忽略了别名和细微差别,例如-?vs -hvs --help。)

    BSDMac OS X 提供 BSD locate

    大多数 Linux 都提供 GNU locate,但 Red Hat Linux 和 Arch 则提供mlocate替代。 Debian 不在其基本安装中安装任何一个版本,但在其默认软件包存储库中提供这两个版本;如果同时安装两者,则locate运行“” mlocate

    Oracle 已mlocate在 Solaris 中发布从 11.2 开始,于 2014 年 12 月发布。在此之前,locateSolaris 上并未默认安装。 (据推测,这样做是为了减少 Solaris 命令与甲骨文Linux,即基于红帽企业Linux,也使用mlocate。)

    IBM AIX仍然没有发布任何版本locate至少从 AIX 7.2 开始,除非您findutils从以下位置安装 GNU适用于 Linux 应用程序的 AIX 工具箱

    惠普-UX出现缺乏locate基础系统。

    年长的“真正的”Unix一般不包括 的实现locate

  • find(1)拥有强大的表达式语法,功能众多,布尔运算符, ETC。

  • find(1)不仅可以通过名称来选择文件。它可以通过以下方式选择:

    • 年龄
    • 尺寸
    • 所有者
    • 文件类型
    • 时间戳
    • 权限
    • 子树内的深度...
  • 当按名称查找文件时,您可以使用以下命令进行搜索文件通配语法在所有版本中find(1),或者在 GNU 或 BSD 版本中,使用常用表达

    当前版本locate(1)也接受 glob 模式find,但 BSDlocate根本不执行正则表达式。如果您像我一样并且必须使用各种机器类型,您会发现自己更喜欢过滤而不是开发对或 的grep依赖。-r--regex

    locate比这更需要强大的过滤,find因为......

  • find(1)不一定搜索整个文件系统。您通常将其指向一个子目录,即包含您希望其操作的所有文件的父目录。实现的典型行为locate(1)是喷出与您的模式匹配的所有文件,将其留给grep过滤等以减少其爆发的大小。

    (邪恶提示:locate /可能会为您提供系统上所有文件的列表!)

    有一些变体locate(1)可以slocate(1)根据用户权限限制输出,但这不是locate任何主要操作系统的默认版本。

  • find(1)做事除了查找它们之外,还可以访问它找到的文件。最强大和最广泛支持的此类运算符是-exec,但还有其他运算符。例如,在最近的 GNU 和 BSD 查找实现中,有-delete-execdir运算符。

  • find(1)实时运行,因此其输出始终是最新的。

    由于locate(1)依赖于过去几小时或几天更新的数据库,因此其输出可能会过时。 (这是陈旧的缓存问题.) 这枚硬币有两个面:

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

      GNUlocatemlocate-e标志让它在打印出过去发现的每个文件的名称之前检查文件是否存在,但这会削弱一些locate速度优势,而且在 BSD 中也不可用locate

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

    你学会了对locate输出有些不信任,因为你知道它可能是错误的。

    有很多方法可以解决这个问题,但我不知道有任何广泛使用的实现。例如,有rlocate, 但它出现不针对任何现代 Linux 内核工作。

  • find(1)永远不会比运行它的用户拥有更多的特权。

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

    1. 以 root 身份运行updatedb,但使其输出文件可供所有人读取,以便locate无需特殊权限即可运行。这有效地将系统中所有文件的名称公开给所有用户。这可能足以引发真正的问题。

      BSDlocate在 Mac OS X 和 FreeBSD 上是这样配置的。

    2. 将数据库写入只能由 读取root,然后 makelocate setuid这样它就可以读取数据库了。这意味着locate实际上意味着必须重新实现操作系统的权限系统,这样它就不会显示您通常无法看到的文件。它还增加了攻击面您的系统,特别是冒着根升级攻击。

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

      mlocate是这样配置的红帽企业 Linux

      但你仍然有一个问题,因为如果你可以使用调试器locate或使其转储核心您可以访问数据库的特权部分。

    我没有找到一种方法来创建真正的“安全”locate命令,除非为系统上的每个用户单独运行它,这否定了它相对于find(1).

总而言之,两者都非常有用。locate(1)当您只是尝试按名称查找特定文件(您知道该文件存在,但您只是不记得它的确切位置)时,这样做会更好。find(1)当您有一个重点领域需要检查时,或者当您需要它的众多优点时,它会更好。

答案2

locate使用预构建的数据库,该数据库应该定期更新,同时find迭代文件系统来定位文件。

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

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

答案3

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

locate灵活性较差,但在常见情况下使用起来更加直观。

答案4

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

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

相关内容