命令行手册

Man » find 在线手册 - find 手册页的详细在线文档

🌍
find - 在目录层次结构中搜索文件

概要

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始点...] [表达式]

描述

本手册页记录了 GNU 版本的 find。GNU find 从每个给定的起始点开始搜索目录树,从左到右评估给定的表达式,按照优先级规则(参见“运算符”部分),直到结果已知(对于 and 运算,左侧为 false;对于 or 运算,左侧为 true),此时 find 移动到下一个文件名。如果未指定起始点,则假定为“.”。

如果您在安全重要的环境中(例如,如果将其用于搜索其他用户可写入的目录)使用 find,则应阅读 findutils 文档的“安全注意事项”章节,该文档名为“查找文件”,并随 findutils 一起提供。该文档还包含比本手册页更多的详细信息和讨论,因此您可能会发现它是一个更有用的信息来源。

选项

-H、-L 和 -P 选项控制符号链接的处理方式。命令行参数,直到第一个以“-”开头的参数或“(”或“!”开头的参数,都将被视为要检查的文件或目录的名称。该参数以及任何后续参数都将被视为描述要搜索的内容的表达式。如果未提供任何路径,则使用当前目录。如果未提供任何表达式,则使用 -print 表达式(但您可能应该考虑使用 -print0 )。

本手册页讨论了表达式列表中的“选项”。这些选项控制 find 的行为,但它们在最后一个路径名之后立即指定。五个“真正的”选项 -H、-L、-P、-D 和 -O 必须出现在第一个路径名之前(如果有的话)。理论上,可以使用双破折号 -- 来指示任何剩余参数都不是选项,但这并不能真正起作用,因为 find 确定以下路径参数的结束方式是通过读取,直到出现一个表达式参数(它也以“-”开头)。现在,如果一个路径参数以“-”开头,那么 find 将其视为表达式参数。因此,为了确保所有起始点都作为起始点,特别是为了防止由调用 shell 扩展的通配符模式被错误地视为表达式参数,通常最好将通配符或可疑的路径名之前加上“./”或使用以“/”开头的绝对路径名。或者,通常可以使用 GNU 选项 -files0-from 将任意起始点传递给 find,但这并非标准。


-P     绝不跟随符号链接。这是默认行为。当 find 检查或打印文件信息时,如果该文件是符号链接,则应使用符号链接本身的属性。

-L     跟随符号链接。当 find 检查或打印文件信息时,应使用链接指向的文件本身的属性,而不是链接本身的属性(除非是损坏的符号链接,或者 find 无法检查链接指向的文件)。使用此选项意味着 -noleaf。如果稍后使用 -P 选项,-noleaf 仍然会生效。如果 -L 生效,并且 find 在搜索过程中发现指向子目录的符号链接,则将搜索符号链接指向的子目录。

当 -L 选项生效时,-type 谓词将始终匹配符号链接指向的文件类型,而不是链接本身(除非符号链接已损坏)。可能导致符号链接在 find 执行期间损坏的操作(例如 -delete)可能会导致令人困惑的行为。使用 -L 会使 -lname 和 -ilname 谓词始终返回 false。

-H     不跟随符号链接,但在处理命令行参数时除外。当 find 检查或打印文件信息时,应使用符号链接本身的属性。唯一的例外是,如果命令行上的文件是符号链接,并且该链接可以被解析。在这种情况下,将使用链接指向的文件(即,跟随链接)的属性。如果无法检查链接指向的文件,则将使用链接本身的属性作为后备。如果 -H 生效,并且命令行中指定的路径是符号链接到目录,则将检查该目录的内容(当然,-maxdepth 0 会阻止这种情况)。

如果指定了多个 -H、-L 和 -P 选项,则每个选项都会覆盖其他选项;命令行中最后一个出现的选项将生效。由于 -P 是默认选项,因此应将其视为生效,除非指定了 -H 或 -L。

GNU find 经常在处理命令行本身之前,在开始任何搜索之前,对文件进行 stat 操作。这些选项还会影响如何处理这些参数。具体来说,有许多测试会将命令行中列出的文件与当前正在考虑的文件进行比较。在每种情况下,命令行中指定的文件的属性都已被检查并保存。如果所述文件实际上是符号链接,并且 -P 选项生效(或者如果未指定 -H 或 -L),则用于比较的信息将取自符号链接的属性。否则,它将取自链接指向的文件的属性。如果 find 无法跟随链接(例如,因为它没有足够的权限,或者链接指向一个不存在的文件),则将使用链接本身的属性。


当使用 -H 或 -L 选项时,作为 -newer 参数传递的任何符号链接都会被取消引用,并且将从符号链接指向的文件获取时间戳。 同样的处理也适用于 -newerXY、-anewer 和 -cnewer。

-follow 选项的作用类似于 -L,但它在出现的位置生效(也就是说,如果未使用 -L 但使用了 -follow,则在命令行中出现 -follow 之后的所有符号链接都将被取消引用,而之前的符号链接则不会)。

-D debugopts
打印诊断信息;这对于诊断为什么 find 没有按你希望的方式工作可能有所帮助。调试选项列表应使用逗号分隔。不同版本的 findutils 之间调试选项的兼容性无法保证。要获取有效的完整调试选项列表,请参阅 find -D help 的输出。有效的调试选项包括:

exec   显示与 -exec、-execdir、-ok 和 -okdir 相关的诊断信息。

opt    打印与表达式树优化相关的诊断信息;请参阅 -O 选项。

rates   打印摘要,指示每个谓词的成功或失败频率。

search 详细地浏览目录树。

stat   打印消息,说明正在使用 stat 和 lstat 系统调用检查文件。find 程序试图尽量减少此类调用。

tree   以原始形式和优化形式显示表达式树。

all    启用所有其他调试选项(但不包括 help)。

help   解释调试选项。

-Olevel
启用查询优化。find 程序会重新排序测试以加快执行速度,同时保留整体效果;也就是说,具有副作用的谓词不会相互重新排序。每个优化级别执行的优化如下。

0     等同于优化级别 1。

1     这是默认优化级别,对应于传统的行为。表达式会重新排序,以便首先执行仅基于文件名称的测试(例如 -name 和 -regex)。

2     任何 -type 或 -xtype 测试都将在仅基于文件名称的测试之后执行,但在需要来自 inode 的信息之前执行。在许多现代版本的 Unix 上,文件类型由 readdir() 返回,因此这些谓词的评估速度比首先需要 stat 文件的谓词更快。如果你使用 -fstype FOO 谓词并指定一个在 find 开始时未知的(即,不存在于 /etc/mtab 中)文件系统类型 FOO,则该谓词等同于 -false。

3     在该优化级别,启用了完整的基于成本的查询优化器。
测试的顺序进行了修改,以便首先执行廉价(即快速)的测试,然后在必要时执行更昂贵的测试。 在每个成本范围内,根据谓词可能成功或失败的情况,对其进行早期或后期评估。 对于 -o,谓词更有可能在早期进行评估,对于 -a,谓词更有可能在早期进行评估。

基于成本的优化器对任何给定测试成功的可能性都有固定的想法。 在某些情况下,概率会考虑到测试的特定性质(例如,-type f 假定比 -type c 更可能成功)。 目前正在评估基于成本的优化器。 如果它实际上没有提高 find 的性能,那么它将被再次删除。 另一方面,如果优化被证明是可靠、稳健和有效的,那么随着时间的推移,它们可能会在较低的优化级别启用。 但是,默认行为(即优化级别 1)不会在 4.3.x 版本系列中更改。 findutils 测试套件在每个优化级别运行所有测试,并确保结果相同。

基于成本的优化器执行的操作的重新排序可能会导致用户可见的行为变化。 例如,-readable 和 -empty 谓词对重新排序很敏感。 如果以 -empty -readable 的顺序运行它们,则会为不可读的目录发出错误消息。 如果以 -readable -empty 的顺序运行它们,则不会发出错误消息。 这就是为什么不执行这种操作重新排序的原因,因为它不会在默认优化级别执行。

表达式

命令行中,在起始点列表之后的部分就是表达式。 这是一个查询规范,描述了我们如何匹配文件以及我们如何处理匹配的文件。 表达式由一系列内容组成:

测试 测试返回一个真值或假值,通常基于我们正在考虑的文件的某个属性。 例如,-empty 测试仅在当前文件为空时才为真。

动作 动作具有副作用(例如,在标准输出上打印某些内容),并且返回一个真值或假值,通常基于它们是否成功。 例如,-print 动作将当前文件的名称打印到标准输出。

全局选项 全局选项会影响在命令行的任何部分中指定的测试和动作的操作。 全局选项始终返回真值。 例如,-depth 选项使 find 以深度优先的顺序遍历文件系统。

位置选项 位置选项仅影响其后的测试或动作。 位置选项始终返回真值。 例如,-regextype 选项是位置选项,它指定命令行中以后出现的正则表达式的正则表达式方言。


运算符 运算符将表达式中的其他项连接在一起。 例如,它们包括 -o(表示逻辑 OR)和 -a(表示逻辑 AND)。 如果缺少运算符,则假定为 -a。

对于整个表达式为 true 的所有文件,都会执行 -print 操作,除非它包含 -prune 或 -quit 以外的其他操作。 抑制默认 -print 操作的操作包括 -delete、-exec、-execdir、-ok、-okdir、-fls、-fprint、-fprintf、-ls、-print 和 -printf。

-delete 操作还充当一个选项(因为它意味着 -depth)。

位置选项

位置选项始终返回 true。 它们仅影响命令行的后续测试。

-daystart

从今天的开始时间而不是从 24 小时前开始测量时间(用于 -amin、-atime、-cmin、-ctime、-mmin 和 -mtime)。 此选项仅影响之后在命令行中出现的测试。

-follow

已弃用;请改用 -L 选项。 取消引用符号链接。 意味着 -noleaf。 -follow 选项仅影响其后在命令行中出现的测试。 除非已指定 -H 或 -L 选项,否则 -follow 选项的位置会改变 -newer 谓词的行为;如果它是符号链接,则作为 -newer 参数列出的任何文件都将被取消引用。 同样,-newerXY、-anewer 和 -cnewer 谓词也适用。 类似地,-type 谓词将始终匹配符号链接指向的文件的类型,而不是链接本身。 使用 -follow 会导致 -lname 和 -ilname 谓词始终返回 false。

-regextype type

更改 -regex 和 -iregex 测试所理解的正则表达式语法,这些测试之后在命令行中出现。 要查看已知的正则表达式类型,请使用 -regextype help。 Texinfo 文档(请参阅 SEE ALSO)解释了各种正则表达式类型的含义和区别。 如果您不使用此选项,则 find 的行为就像指定了 emacs 类型的正则表达式一样。

-warn、-nowarn

启用或禁用警告消息。 这些警告仅适用于命令行用法,不适用于 find 在搜索目录时可能遇到的任何条件。 默认行为与标准输入为 tty 时对应于 -warn,否则对应于 -nowarn。 如果生成与命令行用法相关的警告消息,则 find 的退出状态不会受到影响。 如果设置了 POSIXLY_CORRECT 环境变量,并且也使用了 -warn,则不指定哪些(如果有的话)警告将生效。

全局选项

全局选项始终返回 true。 全局选项即使对于之前在命令行中出现的测试也有效。 为了避免混淆,全局选项应在命令行中列出起始点列表之后,在第一个测试、位置选项或操作之前进行指定。 如果您在其他位置指定全局选项,find 将发出警告消息,解释这可能会造成混淆。


全局选项出现在起始点列表之后,因此与 -L 等选项不同。

-d     -depth 的同义词,用于与 FreeBSD、NetBSD、MacOS X 和 OpenBSD 兼容。

-depth 在处理目录本身之前,先处理每个目录的内容。-delete 操作也意味着 -depth。

-files0-from 文件

从文件而不是命令行获取起始点。与通过命令行参数传递起始点存在的限制(即文件名数量的限制以及文件名与选项名称冲突)相比,使用此选项可以安全地将任意数量的起始点传递给 find。

同时使用此选项并从命令行传递起始点是互斥的,因此不允许同时进行。

文件参数是必需的。可以使用 -files0-from - 从标准输入流读取起始点列表,例如,从管道中读取。在这种情况下,不允许使用 -ok 和 -okdir 操作,因为它们显然会干扰从标准输入读取以获取用户确认。

文件中的起始点必须由 ASCII NUL 字符分隔。两个连续的 NUL 字符,即零长度的文件名,是不允许的,并且会导致错误诊断,之后会返回非零退出代码。

如果给定的文件为空,find 不会处理任何起始点,并且会在解析程序参数后立即退出。这与标准调用方式不同,在标准调用方式中,如果未传递任何路径参数,find 会假定当前目录作为起始点。

起始点的处理方式与通常情况相同,例如,除非另有阻止,否则 find 会递归进入子目录。要仅处理起始点,可以同时传递 -maxdepth 0。

其他说明:如果文件在输入文件中列出多次,则是否多次访问该文件是不确定的。如果文件在 find 运行期间被修改,结果也是不确定的。最后,find 退出时(无论是使用 -quit 还是以任何其他方式退出)在命名文件中的查找位置也是不确定的。这里,“不确定”意味着它可能有效或可能无效,并且行为可能会从一个平台到另一个平台或从一个 findutils 版本到另一个版本而变化。

-help, --help

打印 find 的命令行用法摘要并退出。

-ignore_readdir_race

通常,如果 find 无法 stat 一个文件,它会发出错误消息。如果提供了此选项,并且在 find 从目录读取文件名和尝试 stat 该文件之间,文件被删除,则不会发出错误消息。这也适用于在命令行中给出的文件或目录的名称。此选项在读取命令行时生效,这意味着你不能使用此选项搜索文件系统的一部分,而不使用此选项搜索文件系统的另一部分(如果需要这样做,则需要发出两个 find 命令,一个使用该选项,另一个不使用该选项)。


此外,使用 -ignore_readdir_race 选项的 find 命令会忽略 -delete 操作中出现的文件已消失的错误(即自读取父目录后文件已消失):它不会输出错误诊断,并且 -delete 操作的返回值将为 true。

-maxdepth levels

最多向下搜索 levels(一个非负整数)层目录。使用 -maxdepth 0 表示仅对起始点本身应用测试和操作。

-mindepth levels

不将任何测试或操作应用于小于 levels(一个非负整数)的层级。使用 -mindepth 1 表示处理所有文件,但不包括起始点。

-mount 不要进入其他文件系统上的目录。-xdev 的另一种名称,用于与 find 的其他版本兼容。

-noignore_readdir_race

关闭 -ignore_readdir_race 的效果。

-noleaf

不要通过假设目录包含比其硬链接计数少 2 个子目录来优化。当搜索不遵循 Unix 目录链接约定(如 CD-ROM 或 MS-DOS 文件系统或 AFS 卷挂载点)的文件系统时,需要此选项。正常 Unix 文件系统上的每个目录至少有 2 个硬链接:其名称和其 .' 条目。此外,其子目录(如果有)每个都有一个..' 条目,链接到该目录。当 find 正在检查一个目录时,在它 stat 完比目录的链接计数少 2 个子目录之后,它就知道目录中其余的条目都是非目录(目录树中的“叶子”文件)。如果只需要检查文件的名称,则无需对它们进行 stat 操作;这将大大提高搜索速度。

-version, --version

打印 find 版本号并退出。

-xdev 不要进入其他文件系统上的目录。

测试

某些测试,例如 -newerXY 和 -samefile,允许在当前正在检查的文件和命令行中指定的一些参考文件之间进行比较。当使用这些测试时,参考文件的解释由选项 -H、-L 和 -P 以及任何先前的 -follow 选项确定,但参考文件仅在解析命令行时进行检查一次。如果无法检查参考文件(例如,对于参考文件,stat(2) 系统调用失败),则会发出错误消息,并且 find 将以非零状态退出。


可以将数字参数 n 指定给测试(例如 -amin、-mtime、-gid、-inum、-links、-size、-uid 和 -used),如下所示:

+n     表示大于 n,

-n     表示小于 n,

n      表示等于 n。

支持的测试:

-amin n
文件上次访问时间小于、大于或等于 n 分钟前。

-anewer reference
当前文件的上次访问时间晚于参考文件的上次数据修改时间。如果 reference 是一个符号链接,并且启用了 -H 选项或 -L 选项,则始终使用它指向的文件上次修改的时间。

-atime n
文件上次访问时间小于、大于或等于 n\*24 小时前。当 find 计算文件上次访问时间距离现在多少个 24 小时周期时,会忽略任何小数部分,因此要匹配 -atime +1,文件必须至少在两天前被访问过。

-cmin n
文件的状态上次更改时间小于、大于或等于 n 分钟前。

-cnewer reference
当前文件的上次状态更改时间晚于参考文件的上次数据修改时间。如果 reference 是一个符号链接,并且启用了 -H 选项或 -L 选项,则始终使用它指向的文件上次修改的时间。

-ctime n
文件的状态上次更改时间小于、大于或等于 n\*24 小时前。请参见 -atime 的注释,以了解舍入如何影响文件状态更改时间的解释。

-empty 文件为空,并且是常规文件或目录。

-executable
匹配对当前用户可执行且目录可搜索(在文件名解析意义上)的文件。这会考虑到访问控制列表和其他权限工件,而 -perm 测试会忽略这些。此测试使用 access(2) 系统调用,因此可能会被执行 UID 映射(或根用户权限剥离)的 NFS 服务器欺骗,因为许多系统在客户端内核中实现 access(2),因此无法使用服务器上保存的 UID 映射信息。由于此测试仅基于 access(2) 系统调用的结果,因此无法保证对于此测试成功的文件实际上可以执行。

-false 始终为 false。

-fstype type
文件位于文件系统类型为 type 的文件系统上。不同的 Unix 版本支持的文件系统类型各不相同;在某些版本的 Unix 或其他版本中接受的文件系统类型的不完整列表为:ufs、4.2、4.3、nfs、tmp、mfs、S51K、S52K。可以使用 -printf 选项和 %F 指令来查看文件系统的类型。

-gid n 文件的数字组 ID 小于、大于或等于 n。

-group gname
文件属于组 gname(允许使用数字组 ID)。

-ilname pattern
类似于 -lname,但匹配不区分大小写。如果启用了 -L 选项或 -follow 选项,除非符号链接是损坏的,否则此测试将返回 false。

-iname pattern

类似于 -name,但匹配不区分大小写。例如,模式 fo*F?? 将匹配文件名 FooFOOfoofOo 等。模式 *foo* 也会匹配 名为 .foobar 的文件。

-inum n

文件具有小于、大于或等于 n 的 inode 号。通常使用 -samefile 测试会更容易。

-ipath pattern

类似于 -path,但匹配不区分大小写。

-iregex pattern

类似于 -regex,但匹配不区分大小写。

-iwholename pattern

请参阅 -ipath。此替代方法不如 -ipath 具有可移植性。

-links n

文件具有少于、多于或恰好 n 个硬链接。

-lname pattern

文件是一个符号链接,其内容与 shell 模式 pattern 匹配。元字符 不将 \. 特殊处理。如果启用了 -L 选项或 -follow 选项,则此 测试如果符号链接是损坏的,则返回 false。

-mmin n

文件的最后数据修改时间少于、多于或恰好 n 分钟前。

-mtime n

文件的最后数据修改时间少于、多于或恰好 n*24 小时前。请参阅 -atime 的注释,以了解舍入如何影响文件修改时间的解释。

-name pattern

文件名(删除了前导目录后的路径)与 shell 模式 pattern 匹配。由于删除了文件的前导目录,因此模式 不应包含斜杠,因为 -name a/b 永远不会匹配任何内容(您可能希望使用 -path)。使用单个斜杠作为模式(-name /)是一个例外,因为这是匹配根目录 "/" 的有效字符串(因为 "/" 的基本名称是 "/")。如果您尝试传递包含 - 但不完全由单个 - 斜杠组成的模式,则会发出警告,除非设置了环境变量 POSIXLY_CORRECT 或使用了 -nowarn 选项。

要忽略一个目录及其子目录中的文件,请使用 -prune,而不是检查树中的每个文件;请参阅示例,了解该操作的说明。大括号不被视为 具有特殊含义,尽管某些 shell(包括 Bash)在 shell 模式中赋予大括号特殊含义。文件名匹配是使用 fnmatch(3) 库函数执行的。不要忘记将模式括在引号中,以 防止 shell 进行扩展。

-newer reference

当前文件最后数据修改时间晚于参考文件的最后数据修改时间。如果 reference 是一个符号链接,并且启用了 -H 选项或 -L 选项,则始终使用其指向的文件最后数据修改时间。

-newerXY reference

如果正在考虑的文件的时间戳 X 比文件 reference 的时间戳 Y 更新,则成功。字母 X 和 Y 可以是以下任何字母:


a   文件引用的访问时间
B   文件引用的创建时间
c   引用inode状态更改时间
m   文件引用的修改时间
t   引用被直接解释为时间

某些组合是无效的;例如,如果X为t,则无效。 某些组合并非所有系统都支持;例如,并非所有系统都支持B。 如果指定了无效或不支持的XY组合,则会发生致命错误。 时间 规范的解释方式与GNU date命令的-d选项的参数相同。 如果您尝试使用参考文件的创建时间,并且无法确定创建时间,则会产生致命错误消息。 如果您指定了一个测试,该测试引用了正在检查的文件的创建时间,那么对于任何创建时间未知的,该测试都将失败。

-nogroup
没有与文件数字组ID对应的组。

-nouser
没有与文件数字用户ID对应的用户。

-path 模式
文件名与shell模式`模式`匹配。 元字符不会将\`/\`或\`.\`特殊对待;因此,例如,
find . -path "./sr*sc"
将打印一个名为`./src/misc`的目录(如果存在)。 要忽略整个目录树,请使用`-prune`而不是检查树中的每个文件。 请注意,`-path`参数匹配应用于整个文件名,从命令行中指定的一个或多个起始点开始。 只有当相关的起始点也是绝对路径时,才可以使用绝对路径名。 这意味着以下命令永远不会匹配任何内容:
find bar -path /foo/bar/myfile -print
Find将`-path`参数与目录名和正在检查的文件的基本名的连接进行比较。 由于连接永远不会以斜杠结尾,因此以斜杠结尾的`-path`参数将不会匹配任何内容(除非命令行中指定的起始点也是绝对路径)。 `-path`谓词也受HP-UX find支持,并且是POSIX 2008标准的一部分。

-perm 模式
文件的权限位与`模式`完全匹配(八进制或符号)。 由于需要完全匹配,因此如果您想以符号模式的形式使用它,则可能需要指定相当复杂的模式字符串。 例如,`-perm g=w`只会匹配具有模式0020的文件(即,只有组写权限的文件)。 更可能的是,您希望使用`/`或`-`形式,例如`-perm -g=w`,它匹配具有组写权限的任何文件。 请参见“示例”部分,了解一些说明性示例。

-perm -模式
文件的所有权限位`模式`都已设置。 此形式接受符号模式,并且通常这是您希望使用的形式。 如果使用符号模式,则必须指定`u`、`g`或`o`。 请参见“示例”部分,了解一些说明性示例。

-perm /模式
文件的任何权限位`模式`都已设置。 此形式接受符号模式。 如果使用符号模式,则必须指定`u`、`g`或`o`。 请参见“示例”部分,了解一些说明性示例。 如果`模式`中没有设置任何权限位,则此测试将匹配任何文件(这里的想法与`-perm -000`的行为保持一致)。

-perm +mode
不再支持此选项(自 2005 年起已弃用)。请使用 -perm /mode 代替。

-readable
匹配当前用户可以读取的文件。此选项会考虑访问控制列表和其他权限工件,而 -perm 测试则忽略这些。此测试使用 access(2) 系统调用,因此可能会被使用 UID 映射(或 root 压缩)的 NFS 服务器欺骗,因为许多系统在客户端内核中实现 access(2),因此无法使用服务器上保存的 UID 映射信息。

-regex pattern
文件名匹配正则表达式模式。这是一个对整个路径的匹配,而不是搜索。例如,要匹配名为 ./fubar3 的文件,可以使用正则表达式 `.*bar.` 或 `.*b.*3`,但不能使用 `f.*r3`。find 理解的正则表达式默认是 Emacs 正则表达式,但可以使用 -regextype 选项进行更改。

-samefile name
文件引用与 name 相同的 inode。如果使用了 -L 选项,则可能包括符号链接。

-size n[cwbkMG]
文件使用的空间小于、大于或等于 n 个单位,并向上舍入。可以使用以下后缀:

`b`  表示 512 字节的块(如果未指定后缀,则为默认值)

`c`  表示字节

`w`  表示两个字节的字

`k`  表示千字节 (KiB,1024 字节的单位)

`M`  表示兆字节 (MiB,1024 * 1024 = 1048576 字节的单位)

`G`  表示千兆字节 (GiB,1024 * 1024 * 1024 = 1073741824 字节的单位)

大小只是由 lstat(或 stat)系统调用填充的 struct stat 中的 st_size 成员,如上述所示。换句话说,它与 ls -l 命令的结果一致。请记住,-printf 命令中的 `%k` 和 `%b` 格式说明符对稀疏文件的处理方式不同。`b` 后缀始终表示 512 字节的块,而不是 1024 字节的块,这与 -ls 命令的行为不同。

+ 和 - 前缀表示大于和小于,如通常那样;即,精确大小为 n 个单位时,不会匹配。请记住,大小会向上舍入到下一个单位。因此,-size -1M 不等同于 -size -1048576c。前者仅匹配空文件,后者匹配从 0 到 1,048,575 字节的文件。

-true
始终为真。

-type c
文件类型为 c:

b      块(缓冲)特殊文件

c      字符(非缓冲)特殊文件

d      目录

p      命名管道 (FIFO)

f      普通文件

l      符号链接;如果启用了 -L 选项或 -follow 选项,则此选项永远不会为真,除非符号链接是损坏的。如果要在启用了 -L 选项时搜索符号链接,请使用 -xtype。

s      socket

D      door (Solaris)

要一次搜索多种类型,可以提供用逗号 `,' 分隔的类型字母列表(GNU 扩展)。

-uid n 文件数字用户 ID 小于、大于或等于 n。

-used n

文件最后一次访问时间距其状态最后一次更改的时间小于、大于或等于 n 天。

-user uname

文件由用户 uname 拥有(允许使用数字用户 ID)。

-wholename pattern

请参阅 -path。此替代方法不如 -path 那么通用。

-writable

匹配当前用户可以写入的文件。这将考虑到访问控制列表和其他权限工件,而 -perm 测试会忽略这些。此测试使用 access(2) 系统调用,因此可能会被执行 UID 映射(或 root 压缩)的 NFS 服务器欺骗,因为许多系统在客户端内核中实现 access(2),因此无法使用服务器上保存的 UID 映射信息。

-xtype c

与 -type 相同,除非该文件是符号链接。对于符号链接:如果指定了 -H 或 -P 选项,则如果该文件是链接到类型为 c 的文件,则为真;如果给出了 -L 选项,则如果 c 是 l,则为真。换句话说,对于符号链接,-xtype 检查 -type 不检查的文件类型。如果符号链接已损坏(因为指向的文件不存在或链接指向自身),则 -xtype 的行为将与 -type 相同。

-context pattern

(仅限 SELinux)文件的安全上下文与 glob 模式匹配。

操作

-delete

删除文件或目录;如果删除成功,则返回 true。如果删除失败,将发出错误消息,并且 find 的退出状态将为非零(在最终退出时)。

警告:不要忘记 find 将命令行视为一个表达式,因此首先放置 -delete 将使 find 尝试删除您指定的所有起始点下方的一切。

在命令行中使用 -delete 操作会自动启用 -depth 选项。反过来,-depth 使 -prune 变得无效,因此无法有用地将 -delete 操作与 -prune 结合使用。

通常,用户可能希望在添加 -delete 进行实际删除运行之前,先使用 -print 测试 find 命令行。为了避免产生令人惊讶的结果,最好记住在这些早期的测试运行期间显式使用 -depth。

-delete 操作将无法删除一个非空目录。

与 -ignore_readdir_race 选项一起使用时,如果自读取父目录以来文件已消失,find 将忽略 -delete 操作的错误:它不会输出错误诊断,不会将退出代码更改为非零,并且 -delete 操作的返回代码将为 true。

-exec command ;

执行命令;如果返回 0 状态,则返回 true。find 之后的所有参数都被视为命令的参数,直到遇到由 ;' 组成的参数。字符串{}' 将被当前正在处理的文件名替换,无论它在命令的参数中出现的位置如何,这与某些 find 版本不同。这两个构造可能都需要进行转义(使用 \)或引用,以防止 shell 展开。请参阅示例部分,了解 -exec 选项的用法示例。指定的命令为每个匹配的文件运行一次。命令在起始目录中执行。使用 -exec 操作存在不可避免的安全问题;您应该使用 -execdir 选项。


-exec command {} +

此变体形式的 -exec 操作会对选定的文件运行指定的命令,但命令行是通过将每个选定的文件名附加到末尾构建的;命令的总调用次数将远远少于匹配文件的数量。 命令行构建方式与 xargs 构建命令行的方式非常相似。 只能在命令中使用一个 {} 实例,并且它必须出现在末尾,紧接在 + 之前;需要对其进行转义(使用 \)或引用,以防止 shell 对其进行解释。 该命令在起始目录中执行。 如果任何使用 + 形式的调用返回非零退出状态,则 find 返回非零退出状态。 如果 find 遇到错误,这有时会导致立即退出,因此某些未决命令可能根本无法运行。 出于这个原因,-exec my-command ... {} + -quit 可能不会实际运行 my-command。 此 -exec 变体始终返回 true。

-execdir command ;

-execdir command {} +

类似于 -exec,但指定的命令将在包含匹配文件的子目录中运行,这通常不是您启动 find 的目录。 与 -exec 一样,如果从 shell 调用 find,则应引用 {}。 这是一种更安全的方法,可以避免在解析匹配文件路径时出现竞争条件。 与 -exec 操作一样,-execdir+ 形式将构建命令行以处理多个匹配的文件,但任何给定命令的调用仅会列出存在于同一子目录中的文件。 如果您使用此选项,则必须确保 PATH 环境变量不引用 .;否则,攻击者可以通过在您将运行 -execdir 的目录中留下一个具有适当名称的文件来运行任何他们想要的命令。 同样适用于 PATH 中包含空条目或非绝对目录名称的情况。 如果任何使用 + 形式的调用返回非零退出状态,则 find 返回非零退出状态。 如果 find 遇到错误,这有时会导致立即退出,因此某些未决命令可能无法运行。 该操作的结果取决于是使用 + 还是 ; 变体;-execdir command {} + 始终返回 true,而 -execdir command {} ; 仅在命令返回 0 时才返回 true。


-fls 文件
真;类似于 -ls,但像 -fprint 一样写入文件。输出文件始终会创建,即使谓词从未匹配。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。

-fprint 文件
真;将完整文件名打印到文件 文件。如果文件在运行 find 时不存在,则会创建该文件;如果存在,则会被截断。文件 /dev/stdout 和 /dev/stderr 会被特殊处理;它们分别引用标准输出和标准错误输出。输出文件始终会创建,即使谓词从未匹配。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。

-fprint0 文件
真;类似于 -print0,但像 -fprint 一样写入文件。输出文件始终会创建,即使谓词从未匹配。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。

-fprintf 文件 格式
真;类似于 -printf,但像 -fprint 一样写入文件。输出文件始终会创建,即使谓词从未匹配。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。

-ls 真;以 ls -dils 格式将当前文件列表打印到标准输出。块计数为 1KB 块,除非设置了环境变量 POSIXLY_CORRECT,在这种情况下,使用 512 字节块。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。

-ok 命令;

类似于 -exec,但在运行命令之前会询问用户。如果用户同意,则运行该命令。否则,直接返回 false。如果命令运行,其标准输入将从 /dev/null 重定向。此操作不能与 -files0-from 选项一起指定。

对提示的响应与一对正则表达式进行匹配,以确定它是否为肯定或否定响应。该正则表达式是从系统中获取的,如果设置了 POSIXLY_CORRECT 环境变量,或者从 find 的消息翻译中获取。如果系统没有合适的定义,则 find 将使用它自己的定义。无论哪种情况,正则表达式的解释都将受到环境变量 LC_CTYPE(字符类)和 LC_COLLATE(字符范围和等效类)的影响。

-okdir 命令;

类似于 -execdir,但在以与 -ok 相同的方式询问用户之前运行命令。如果用户不同意,则直接返回 false。如果命令运行,其标准输入将从 /dev/null 重定向。此操作不能与 -files0-from 选项一起指定。

-print 真;将完整文件名打印到标准输出,后跟一个换行符。如果您将 find 的输出管道传输到另一个程序,并且搜索的文件中可能包含换行符,那么您应该认真考虑使用 -print0 选项而不是 -print。请参见“不寻常的文件名”部分,了解如何处理文件名中的不寻常字符。


-print0
True; 在标准输出上打印完整的文件名,后跟一个空字符(而不是 -print 使用的换行符)。 这允许包含换行符或其他类型空白的文件名被正确地解释,以便处理 find 输出的程序。 此选项对应于 xargs 的 -0 选项。

-printf format
True; 在标准输出上打印格式,解释转义字符 `\` 和 `%` 指令。 字段宽度和精度可以像 [printf]({filename}../../printf)(3) C 函数一样指定。 请注意,许多字段都以 %s 形式打印,而不是 %d 形式,这意味着标志可能不会像您期望的那样工作。 这也意味着 `-` 标志有效(它强制字段左对齐)。 与 -print 不同,-printf 不会在字符串末尾添加换行符。 转义字符和指令如下:

\a     警报铃。

\b     退格。

\c     立即停止从此格式打印并刷新输出。

\f     分页符。

\n     换行符。

\r     回车符。

\t     水平制表符。

\v     垂直制表符。

\0     ASCII NUL。

\\     文字反斜杠 (`\`)。

\NNN   其 ASCII 码为 NNN(八进制)的字符。

`\` 字符后跟任何其他字符都被视为普通字符,因此它们都将被打印。

%%     文字百分号。

%a     文件的最后访问时间,格式由 C ctime(3) 函数返回。

%Ak    文件的最后访问时间,格式由 k 指定,k 要么是 `@`,要么是 C strftime(3) 函数的指令。 以下显示了 k 的可能值的简化列表。 请参阅 strftime(3) 的文档以获取完整的列表。 由于 strftime(3) 库函数的实现不同,因此某些转换说明符字符可能并非在所有系统上都可用。

@      自 1970 年 1 月 1 日 00:00 GMT 以来经过的秒数,包括小数部分。

时间字段:

H      小时 (00..23)

I      小时 (01..12)

k      小时 (0..23)

l      小时 (1..12)

M      分钟 (00..59)

p      区域设置的 AM 或 PM

r      12 小时制时间 (hh:mm:ss [AP]M)

S      秒 (00.00 .. 61.00)。 包含小数部分。

T      24 小时制时间 (hh:mm:ss.xxxxxxxxxx)

+      日期和时间,由 `+` 分隔,例如 `2004-04-28+22:22:05.0`。 这是一个 GNU 扩展。 时间以当前时区给出(可能受设置 TZ 环境变量的影响)。 秒字段包括小数部分。

X      区域设置的时间表示形式 (H:M:S)。 秒字段包括小数部分。

Z      时区(例如,EDT),如果无法确定,则为空。

日期字段:

a      区域设置的缩写星期几名称(Sun..Sat)

A      区域设置的完整星期几名称,长度可变(Sunday..Saturday)

b      区域设置的缩写月份名称(Jan..Dec)

B      区域设置的完整月份名称,长度可变(January..December)

c      区域设置的日期和时间(Sat Nov 04 12:02:33 EST 1989)。格式与 ctime(3) 相同,因此为了与该格式兼容,秒字段中没有小数部分。

d      月份中的日期(01..31)

D      日期(mm/dd/yy)

F      日期(yyyy-mm-dd)

h      与 b 相同

j      一年中的第几天(001..366)

m      月份(01..12)

U      一年中的星期数,星期日为一周的第一天(00..53)

w      星期几(0..6)

W      一年中的星期数,星期一为一周的第一天(00..53)

x      区域设置的日期表示形式(mm/dd/yy)

y      年份的最后两位数字(00..99)

Y      年份(1970...)

%b     此文件使用的磁盘空间量,以 512 字节块为单位。由于磁盘空间以文件系统块大小的倍数分配,因此通常大于 %s/512,但如果文件是稀疏文件,则也可能更小。

%Bk    文件的创建时间,即其创建时间,格式由 k 指定,与 %A 相同。如果底层操作系统或文件系统不支持创建时间,则此指令将生成一个空字符串。

%c     文件的上次状态更改时间,格式与 C 函数 ctime(3) 返回的格式相同。

%Ck    文件的上次状态更改时间,格式由 k 指定,与 %A 相同。

%d     文件在目录树中的深度;0 表示该文件是起始点。

%D     文件所在的设备的设备编号(struct stat 的 st_dev 字段),以十进制表示。

%f     打印基本名称;文件的名称,不带任何前导目录(仅保留最后一个元素)。对于 /,结果为 /。请参见“示例”部分。

%F     文件所在的类型的文件系统;此值可用于 -fstype。

%g     文件的组名,或者如果该组没有名称,则为数字组 ID。

%G     文件的数字组 ID。

%h     目录名;文件名称的前导目录(所有内容,但最后一个元素除外)。如果文件名不包含斜杠(因为它位于当前目录中),则 %h 规范符将扩展为 .。对于本身是目录并且包含斜杠(包括 /)的文件,%h 扩展为空字符串。请参见“示例”部分。

%H     找到文件时的起始点。

%i     文件的 inode 编号(十进制)。

%k     此文件使用的磁盘空间量,以 1 KB 块为单位。由于磁盘空间以文件系统块大小的倍数分配,因此通常大于 %s/1024,但如果文件是稀疏文件,则也可能更小。

%l     符号链接的目标(如果文件不是符号链接,则为空字符串)。

%m     文件的权限位(八进制)。此选项使用“传统”数字,这是大多数 Unix 实现使用的数字,但如果您的特定实现使用不寻常的八进制权限位排序,则您会看到文件模式的实际值与 %m 的输出之间的差异。通常,您希望在此数字前面添加一个前导零,为此,您应该使用 # 标志(例如,%#m)。

%M 文件权限(以符号形式显示,类似于 `ls` 命令)。此指令在 findutils 4.2.5 及更高版本中支持。

%n 文件硬链接的数量。

%p 文件的名称。

%P 文件的名称,其中移除了找到该文件时的起始路径名称。

%s 文件的大小,以字节为单位。

%S 文件的稀疏度。计算方法为 (BLOCKSIZE * st_blocks / st_size)。对于特定长度的普通文件,您获得的确切值将取决于系统。但是,通常稀疏文件的值将小于 1.0,而使用间接块的文件可能具有大于 1.0 的值。通常,文件使用的块数取决于文件系统。用于 BLOCKSIZE 的值取决于系统,但通常为 512 字节。如果文件大小为零,则打印的值未定义。在不支持 st_blocks 的系统上,文件的稀疏度假定为 1.0。

%t 文件的最后修改时间,格式与 C 语言中的 `ctime(3)` 函数返回的格式相同。

%Tk 文件的最后修改时间,格式由 `k` 指定,与 `%A` 相同。

%u 文件的用户名称,或者如果用户没有名称,则为数字用户 ID。

%U 文件的数字用户 ID。

%y 文件的类型(类似于 `ls -l` 命令中的类型),`U` 表示未知类型(不应发生)。

%Y 文件的类型(类似于 `%y`),并跟踪符号链接:`L` 表示循环,`N` 表示不存在,`?` 表示确定符号链接目标的类型时发生的任何其他错误。

%Z(仅限 SELinux)文件的安全上下文。

%{ %[ %(
保留供将来使用。

以 `%` 开头的字符,后跟任何其他字符,将被丢弃,但该其他字符将被打印(不要依赖此行为,因为可能会引入其他格式字符)。如果在格式字符串的末尾出现 `%`,则行为未定义,因为没有后续字符。在某些语言环境中,这可能会隐藏您的门钥匙,而在其他语言环境中,这可能会删除您正在阅读的小说中的最后一页。

`%m` 和 `%d` 指令支持 `#`、`0` 和 `+` 标志,但其他指令不支持这些标志,即使它们打印数字。不支持这些标志的数值指令包括 `G`、`U`、`b`、`D`、`k` 和 `n`。`-` 格式标志受支持,并且会将字段的对齐方式从右对齐(默认)更改为左对齐。

请参阅“非标准文件名”部分,以了解如何处理文件名中的非标准字符。

-prune 如果文件是目录,则不进入该目录。如果指定了 `-depth` 选项,则 `-prune` 无效。由于 `-delete` 选项隐含 `-depth` 选项,因此无法有意义地同时使用 `-prune` 和 `-delete` 选项。例如,要跳过目录 `src/emacs` 以及其下的所有文件和目录,并打印找到的其他文件的名称,请执行以下操作:
```
find . -path ./src/emacs -prune -o -print
```

-quit 立即退出(如果未发生错误,则返回值为零)。这与 -prune 不同,因为 -prune 仅适用于修剪目录的内容,而 -quit 只是使 find 立即停止。不会留下任何子进程。通过 -exec ... + 或 -execdir ... + 构建的任何命令行将在程序退出之前被调用。执行 -quit 后,不再处理命令行中指定的文件。例如,`find /tmp/foo /tmp/bar -print -quit` 将仅打印 `/tmp/foo`。
-quit 的一个常见用途是在找到所需内容后停止搜索文件系统。例如,如果我们只想找到一个文件,我们可以这样做:
find / -name needle -print -quit

运算符

按优先级递减的顺序排列:

( expr )

强制优先级。由于括号对 shell 具有特殊含义,因此通常需要对其进行引用。本手册中的许多示例使用反斜杠来做到这一点:\(...\)' 而不是(...)`。

! expr 如果 expr 为假,则为真。此字符通常也需要进行保护,以防止 shell 进行解释。

-not expr

与 ! expr 相同,但不符合 POSIX 标准。

expr1 expr2

连续的两个表达式被视为通过隐式 -a 连接;如果 expr1 为假,则不会对 expr2 进行求值。

expr1 -a expr2

与 expr1 expr2 相同。

expr1 -and expr2

与 expr1 expr2 相同,但不符合 POSIX 标准。

expr1 -o expr2

或;如果 expr1 为真,则不会对 expr2 进行求值。

expr1 -or expr2

与 expr1 -o expr2 相同,但不符合 POSIX 标准。

expr1 , expr2

列表;始终对 expr1 和 expr2 进行求值。expr1 的值将被丢弃;列表的值是 expr2 的值。逗号运算符对于一次遍历文件系统层次结构并搜索多种不同类型的事物可能很有用。 -fprintf 操作可用于将各种匹配的项列入多个不同的输出文件。

请注意,-a 在隐式指定时(例如,两个测试出现在没有显式运算符的情况下),或者显式指定时,其优先级高于 -o。这意味着 find . -name afile -o -name bfile -print 将永远不会打印 afile。

不寻常的文件名

find 的许多操作都会导致打印受其他用户控制的数据。这包括文件名、大小、修改时间等。文件名可能是一个问题,因为它们可以包含任何字符,但 \0/ 除外。文件名中的不寻常字符可能会对您的终端产生意外且通常是不良的影响(例如,在某些终端上更改函数键的设置)。各种操作以不同的方式处理不寻常的字符,如下所述。


-print0, -fprint0

始终以精确的文件名形式打印,即使输出是发送到终端。

-ls, -fls

不寻常的字符始终进行转义。空格、反斜杠和双引号字符使用 C 风格的转义方式打印(例如 \f\")。其他不寻常的字符使用八进制转义方式打印。其他可打印字符(对于 -ls 和 -fls,这些是介于八进制 041 和 0176 之间的字符)按原样打印。

-printf, -fprintf

如果输出不是发送到终端,则按原样打印。否则,结果取决于使用哪个指令。指令 %D、%F、%g、%G、%H、%Y 和 %y 扩展为不受文件所有者控制的值,因此按原样打印。指令 %a、%b、%c、%d、%i、%k、%m、%M、%n、%s、%t、%u 和 %U 具有受文件所有者控制的值,但不能用于向终端发送任意数据,因此这些按原样打印。指令 %f、%h、%l、%p 和 %P 会被引用。这种引用方式与 GNU ls 相同。这与 -ls 和 -fls 使用的引用机制不同。如果您可以决定使用哪种格式来格式化 find 的输出,通常最好使用 \0 作为终止符,而不是使用换行符,因为文件名可以包含空格和换行符。LC_CTYPE 环境变量的设置用于确定需要哪些字符进行引用。

-print, -fprint

引用方式与 -printf 和 -fprintf 相同。如果您在脚本中使用 find,或者在匹配的文件可能具有任意名称的情况下,您应该考虑使用 -print0 而不是 -print。

-ok 和 -okdir 操作以原样打印当前文件名。这可能会在未来的版本中更改。

标准兼容性

为了最接近 POSIX 标准,您应该设置 POSIXLY_CORRECT 环境变量。以下选项在 POSIX 标准(IEEE Std 1003.1-2008, 2016 Edition)中指定:

-H     此选项受支持。

-L     此选项受支持。

-name  此选项受支持,但 POSIX 兼容性取决于系统 fnmatch(3) 库函数的 POSIX 兼容性。截至 findutils-4.2.2,shell 元字符(例如 `*`、`?` 或 `[]`)匹配前导 `.`,因为 IEEE PASC 解释 126 要求如此。这是 findutils 早期版本的一个更改。

-type  受支持。POSIX 指定 `b`、`c`、`d`、`l`、`p`、`f` 和 `s`。GNU find 还支持 `D`,代表 Door,由操作系统提供。此外,GNU find 允许一次指定多个类型,以逗号分隔的列表形式。

-ok    受支持。响应的解释遵循通过设置 LC_MESSAGES 环境变量选择的 `yes` 和 `no` 模式。当设置 POSIXLY_CORRECT 环境变量时,这些模式将采用系统定义的肯定(yes)或否定(no)响应。请参阅系统的文档,特别是 nl_langinfo(3),尤其是 YESEXPR 和 NOEXPR。当未设置 POSIXLY_CORRECT 时,这些模式将来自 find 自己的消息目录。

-newer 支持。如果指定的文件是符号链接,则始终会对其进行取消引用。
这是一个与先前行为的变化,先前行为会从符号链接中获取相关时间;请参阅下面的“历史记录”部分。

-perm 支持。如果未设置 POSIXLY_CORRECT 环境变量,则某些模式参数(例如 +a+x),在 POSIX 中无效,但为了向后兼容而得到支持。

其他主要选项 ^ atime-ctime-depth-exec-group-links-mtime-nogroup-nouser、 ^ ok-path-print-prune-size-user-xdev 这些选项均受支持。

POSIX 标准规定了括号 ()、否定 ! 和逻辑 AND/OR 运算符 -a-o

所有其他选项、谓词、表达式等都是超出 POSIX 标准的扩展。其中许多扩展并非 GNU find 所独有。

POSIX 标准要求 find 检测循环:

find 实用程序应检测无限循环;即进入先前访问过的目录,该目录是上次遇到文件的祖先。当它检测到无限循环时,find 应该将诊断消息写入标准错误,并恢复其在目录结构中的位置或终止。

GNU find 符合这些要求。包含指向祖先的硬链接条目的目录的链接计数通常会低于其应有的值。这意味着 GNU find 有时会优化掉对实际上是链接到祖先的子目录的访问。由于 find 实际上不进入这样的子目录,因此它可以避免发出诊断消息。尽管这种行为可能有些令人困惑,但不太可能有人真正依赖于这种行为。如果使用 -noleaf 关闭了叶优化,则始终会检查目录条目,并在适当的情况下发出诊断消息。符号链接不能用于创建文件系统循环,但是,如果使用 -L 选项或 -follow 选项,则当 find 遇到符号链接循环时,会发出诊断消息。与包含硬链接的循环一样,叶优化通常意味着 find 知道它不需要对符号链接调用 stat()chdir(),因此通常不需要此诊断。

^ d 选项是为了与各种 BSD 系统兼容而支持的,但您应该使用符合 POSIX 标准的选项 -depth


POSIXLY_CORRECT 环境变量不会影响 -regex 或 -iregex 测试的行为,因为这些测试并未在 POSIX 标准中指定。

环境变量

LANG 为未设置或为空的国际化变量提供默认值。

LC_ALL 如果设置为非空字符串值,则会覆盖所有其他国际化变量的值。

LC_COLLATE
POSIX 标准规定,此变量会影响用于 -name 选项的模式匹配。GNU find 使用 fnmatch(3) 库函数,因此对 LC_COLLATE 的支持取决于系统库。此变量还会影响对 -ok 响应的解释;虽然 LC_MESSAGES 变量选择用于解释 -ok 响应的实际模式,但模式中任何方括号表达式的解释都将受到 LC_COLLATE 的影响。

LC_CTYPE
此变量会影响用于正则表达式和 -name 测试的字符类的处理方式,如果系统的 fnmatch(3) 库函数支持此功能。此变量还会影响用于解释 -ok 提示符中使用的正则表达式中的任何字符类的解释。LC_CTYPE 环境变量还会影响在打印文件名时哪些字符被视为不可打印字符;请参阅“非同寻常的文件名”部分。

LC_MESSAGES

确定要用于国际化消息的语言环境。如果设置了 POSIXLY_CORRECT 环境变量,它还会确定对 -ok 操作的提示符的响应的解释。

NLSPATH

确定国际化消息目录的位置。

PATH 影响用于查找由 -exec、-execdir、-ok 和 -okdir 调用可执行文件时搜索的目录。

POSIXLY_CORRECT

确定 -ls 和 -fls 使用的块大小。如果设置了 POSIXLY_CORRECT,则块为 512 字节的单位。否则,它们是 1024 字节的单位。

设置此变量还会禁用警告消息(即,默认情况下表示 -nowarn),因为 POSIX 要求,除了 -ok 的输出之外,所有打印到 stderr 的消息都必须是诊断信息,并且必须导致非零退出状态。

当未设置 POSIXLY_CORRECT 时,-perm +zzz 的处理方式与 +zzz 不是有效符号模式时 -perm /zzz 的处理方式相同。当设置了 POSIXLY_CORRECT 时,此类构造会被视为错误。

当设置了 POSIXLY_CORRECT 时,对 -ok 操作的提示符的响应会根据系统消息目录进行解释,而不是根据 find 自己的消息翻译进行解释。

TZ 影响 -printf 和 -fprintf 的某些与时间相关的格式指令所使用的时间区。

示例

简单的 find|xargs 方法

在 /tmp 目录及其子目录中查找名为 core 的文件并删除它们。

$ find /tmp -name core -type f -print | xargs /bin/rm -f

请注意,如果文件名中包含换行符、单引号或双引号或空格,则此方法将无法正常工作。


更安全的 find -print0 | xargs -0 方法

/tmp 目录及其子目录中查找名为 core 的文件并删除它们,以处理包含单引号、双引号、空格或换行符的文件或目录名。

$ find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f

^ name 测试在 -type 测试之前进行,以避免对每个文件调用 [stat]({filename}../../stat)(2)

请注意,在 find 遍历目录树并打印匹配的文件名与 xargs 执行的进程处理该文件之间,仍然存在竞争条件。

处理任意起始点

假设另一个程序 proggy 对文件进行预过滤,并创建一个巨大的以空字符分隔的文件列表,将这些文件作为起始点进行处理,并查找所有常规的空文件:

$ proggy | find -files0-from - -maxdepth 0 -type f -empty

使用 -files0-from - 表示从标准输入(即管道)读取起始点的名称;-maxdepth 0 确保仅检查明确指定的条目,而不递归到目录中(如果其中一个起始点是目录)。

对每个文件执行命令

在当前目录及其子目录中的每个文件上运行 file 命令。

$ find . -type f -exec file '{}' \;

请注意,大括号用单引号括起来,以防止它们被解释为 shell 脚本中的标点符号。分号也用反斜杠进行转义,但也可以使用单引号。

在许多情况下,可能更喜欢使用 -exec ... + 或更好的 -execdir ... + 语法,以提高性能和安全性。

仅遍历一次文件系统 - 用于执行两个不同的操作

仅遍历一次文件系统,将设置用户 ID 的文件和目录列出到 /root/suid.txt,并将大文件列出到 /root/big.txt

$ find / \
\( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
\( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)

此示例使用行继续字符 \ 在前两行中,指示 shell 将命令继续读取到下一行。

按文件年龄搜索

在您的主目录中搜索在过去二十四小时内修改过的文件。

$ find $HOME -mtime 0

此命令的工作原理是,每个文件的最后修改时间除以 24 小时,并丢弃任何余数。这意味着要匹配 -mtime 0,文件必须在过去 24 小时内进行修改。

按文件权限搜索

搜索 /sbin/usr/sbin 中可执行但不可读的文件。

$ find /sbin /usr/sbin -executable \! -readable -print

搜索具有所有者和组的读取和写入权限,但其他用户只能读取而不能写入的文件。


$ find . -perm 664

匹配具有这些标准的文件的同时,也会匹配具有其他权限位的其他文件(例如,如果某人可以执行该文件)。

搜索具有以下权限的文件:其所有者和组具有读取和写入权限,并且其他用户可以读取,而无需考虑是否存在任何额外的权限位(例如,可执行位)。

$ find . -perm -664

这将匹配具有模式 0777 的文件,例如。

搜索可以由某人写入的文件(其所有者、其组或任何其他人)。

$ find . -perm /222

搜索可以由其所有者或其组写入的文件。

$ find . -perm /220
$ find . -perm /u+w,g+w
$ find . -perm /u=w,g=w

这三个命令做的事情相同,但第一个命令使用八进制表示文件模式,而其他两个命令使用符号形式。 这些文件不必同时具有所有者和组的写入权限才能匹配;两者之一即可。

搜索同时具有所有者和组的写入权限的文件。

$ find . -perm -220
$ find . -perm -g+w,u+w

这两个命令做的事情相同。

一个关于权限的更复杂的搜索。

$ find . -perm -444 -perm /222 \! -perm /111
$ find . -perm -a+r -perm /a+w \! -perm /a+x

这两个命令都搜索具有以下条件的文件:对每个人都可读(-perm -444 或 -perm -a+r),至少有一个写入位设置(-perm /222 或 -perm /a+w),但对每个人都不可执行(! -perm /111 或 ! -perm /a+x)。

剪枝 - 忽略文件和子目录

将 /source-dir 的内容复制到 /dest-dir,但忽略名为 .snapshot(以及其中的任何内容)的文件和目录。 它还会忽略名称以 `\~\' 结尾的文件或目录,但不会忽略其内容。

$ cd /source-dir
$ find . -name .snapshot -prune -o \( \! -name '*~' -print0 \) \
| cpio -pmd0 /dest-dir

-prune -o ( ... -print0 ) 这种结构非常常见。 这里,-prune 之前的表达式匹配要被剪枝的事物。 但是,-prune 操作本身返回 true,因此,-o 确保右侧仅对未应用 -prune 的那些目录进行评估(剪枝的目录的内容甚至不会被访问,因此它们的内容是无关的)。 右侧的表达式用括号括起来,只是为了清晰起见。 它强调 -print0 操作仅对未应用 -prune 的事物执行。 由于默认的 and 条件在测试之间比 -o 绑定得更紧密,因此默认情况下就是这样,但括号有助于显示正在发生的事情。

给定以下项目目录及其关联的 SCM 管理目录,执行一个高效的搜索以查找项目的根目录:

$ find repo/ \
\( -exec test -d '{}/.svn' \; \
-or -exec test -d '{}/.git' \; \
-or -exec test -d '{}/CVS' \; \
\) -print -prune

示例输出:

repo/project1/CVS
repo/gnu/project2/.svn
repo/gnu/project3/.svn
repo/gnu/project3/src/.svn
repo/project4/.git

在这个例子中,-prune 阻止了对已经发现的目录进行不必要的递归,例如,我们不会搜索 project3/src,因为我们已经找到了 project3/.svn,但它确保了兄弟目录(project2 和 project3)被找到。

其他有用的例子

搜索多种文件类型。

$ find /tmp -type f,d,l

在目录 /tmp 中搜索文件、目录和符号链接,并将这些类型作为逗号分隔的列表传递(GNU 扩展),否则与更长的、但更具可移植性的方法等效:

$ find /tmp \( -type f -o -type d -o -type l \)

搜索具有特定名称 needle 的文件,并在找到第一个文件时立即停止。

$ find / -name needle -print -quit

演示 -printf 动作的 %f 和 %h 格式指令在某些特殊情况下的解释。这里是一个包含一些输出的示例。

$ find . .. / /tmp /tmp/TRACE compile compile/64/tests/find -maxdepth 0 -printf '[%h][%f]\n'
[.][.]
[.][..]
[][/]
[][tmp]
[/tmp][TRACE]
[.][compile]
[compile/64/tests][find]

退出状态

如果所有文件都已成功处理,find 将以状态 0 退出,如果发生错误,则以大于 0 的状态退出。

这是一个非常宽泛的描述,但如果返回值为非零,则不应依赖 find 结果的正确性。

当发生一些错误时,find 可能会立即停止,而不会完成所有指定的动作。例如,某些起始点可能未被检查,或者 -exec ... {} + 或 -execdir ... {} + 的某些待定程序调用可能未被执行。

历史

一个 find 程序出现在 Version 5 Unix 中,作为 Programmer's Workbench 项目的一部分,由 Dick Haight 编写。Doug McIlroy 的 A Research UNIX Reader: Annotated Excerpts from the Programmer’s Manual, 1971-1986 提供了更多详细信息;你可以在线阅读它,网址为 [https://www.cs.dartmouth.edu/~doug/reader.pdf]。

GNU find 最初由 Eric Decker 编写,David MacKenzie、Jay Plett 和 Tim Wood 对其进行了增强。find -print0 和 xargs -0 的想法来自 Dan Bernstein。

兼容性

从 findutils-4.2.2 开始,文件名模式中使用的 shell 元字符(例如 `*'、`?' 或 `[]')将匹配前导 `.', 因为 IEEE POSIX 解释 126 要求这样做。

从 findutils-4.3.3 开始,-perm /000 现在匹配所有文件,而不是不匹配任何文件。

纳秒分辨率的时间戳是在 findutils-4.3.3 中实现的。

从 findutils-4.3.11 开始,-delete 动作在失败时将 find 的退出状态设置为非零值。但是,find 不会立即退出。 之前,-delete 的失败不会影响 find 的退出状态。 特性 添加到 同时出现在 -files0-from 4.9.0 -newerXY 4.3.3 BSD -D 4.3.1 -O 4.3.1 -readable 4.3.0 -writable 4.3.0 -executable 4.3.0 -regextype 4.2.24 -exec ... + 4.2.12 POSIX -execdir 4.2.12 BSD -okdir 4.2.12 -samefile 4.2.11 -H 4.2.5 POSIX -L 4.2.5 POSIX -P 4.2.5 BSD -delete 4.2.3 -quit 4.2.3 -d 4.2.3 BSD -wholename 4.2.0 -iwholename 4.2.0 -ignore_readdir_race 4.2.0 -fls 4.0 -ilname 3.8 -iname 3.8 -ipath 3.8 -iregex 3.8


在 findutils-4.5.12 中,-perm +MODE 语法已被移除,取而代之的是 -perm /MODE。+MODE 语法自 findutils-4.2.21(于 2005 年发布)起已被弃用。

非错误

操作符优先级问题

命令 find . -name afile -o -name bfile -print 将永远不会打印 afile,因为这实际上等同于 find . -name afile -o (-name bfile -a -print )。请记住,-a 的优先级高于 -o,并且在测试之间未指定运算符时,假定为 -a。

“路径必须先于表达式”错误消息 $ find . -name *.c -print find: 路径必须先于表达式 find: 可能存在未引用的模式,位于谓词 `-name'?

当 shell 可以将模式 *.c 扩展为当前目录中存在的一个或多个文件名时,就会发生这种情况,并将结果文件名作为命令行参数传递给 find,如下所示: find . -name frcode.c locate.c word_io.c -print 该命令当然无法正常工作,因为 -name 谓词仅允许一个模式作为参数。与其这样操作,您应该将模式括在引号中或转义通配符,从而允许 find 在搜索文件名匹配期间使用带有通配符的模式,而不是由父 shell 扩展的文件名: $ find . -name '*.c' -print $ find . -name *.c -print

错误

POSIX 标准中为 find 指定的行为存在固有的安全问题,因此无法修复。例如,-exec 操作本质上是不安全的,应该使用 -execdir 代替。

环境变量 LC_COLLATE 对 -ok 操作没有影响。

报告错误

GNU findutils 在线帮助:https://www.gnu.org/software/findutils/#get-help 将任何翻译错误报告到 https://translationproject.org/team/ 通过 GNU Savannah 错误跟踪器中的表单报告任何其他问题: https://savannah.gnu.org/bugs/?group=findutils 有关 GNU findutils 包的一般主题在 bug-findutils 邮件列表中讨论: https://lists.gnu.org/mailman/listinfo/bug-findutils

版权

版权所有 © 1990–2024 自由软件基金会。许可证 GPLv3+:GNU GPL 版本 3 或更高版本 https://gnu.org/licenses/gpl.html。 这是一份自由软件:您可以自由地更改和重新分发它。在法律允许的范围内,不提供任何保证。


参见

chmod(1), locate(1), ls(1), updatedb(1), xargs(1), lstat(2), stat(2), ctime(3) fnmatch(3), printf(3), strftime(3), locatedb(5), regex(7)

完整文档 [https://www.gnu.org/software/findutils/find] 或者可以在本地通过以下方式获取:info find