docs(find命令): 拓展`find`命令描述以及补充额外的表达式选项 (#593)

This commit is contained in:
hotdogc1017 2024-07-15 10:19:49 +08:00 committed by GitHub
parent 071e0c0aa1
commit e479f15adf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 369 additions and 30 deletions

View File

@ -3,18 +3,43 @@ find
在指定目录下查找文件
## 解释
从每个指定的起始点 (目录) 开始,搜索以该点为根的目录树,并按照运算符优先级规则**从左至右**评估给定的表达式,直到结果确定,此时`find`会继续处理下一个文件名。
## 补充说明
**find命令** 用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时不设置任何参数则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。
本文列出的选项指的是**表达式列表中的选项**。这些选项控制了`find`的行为,需在**最后一个路径名之后**立即指定
### 语法
五个真实选项: `-H、-L、-P、-D 和 -O`。如果出现,**必须位于第一个路径名之前**。关于这部分内容本文不做描述,具体内容可参考[man7.org中的find](https://man7.org/linux/man-pages/man1/find.1.html#top_of_page)
如果使用该命令时,不设置任何参数,则`find`命令将在当前目录下查找子目录与文件,并且将查找到的子目录和文件全部进行显示。等效于以下命令:
```shell
find(选项)(参数)
find . -print
```
### 选项
## 语法
```shell
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始点...] [表达式]
```
忽略真实选项后 (更为常见):
```shell
find [起始点...] [表达式]
```
## 表达式分类
起始点(列表)之后的部分是表达式。这是一种**查询规范**,描述了我们如何匹配文件(返回**真**或者**假**)以及对匹配到的文件进行何种操作。表达式由一系列元素组成:
- 测试Tests测试返回一个真或假值通常基于我们正在考虑的文件的某个属性。例如`-empty`测试仅在当前文件为空时为真。
- 操作Actions操作具有副作用例如在标准输出上打印内容并返回真或假通常基于它们是否成功。例如`-print`操作会在标准输出上打印当前文件的名称。
- 全局Global全局选项影响命令行中任何部分指定的测试和操作的执行。全局选项始终返回真值。例如`-depth`选项使find以深度优先的顺序遍历文件系统。
- 位置Positional位置选项仅影响其后的测试或操作。位置选项始终返回真值。例如`-regextype`选项是位置选项,用于指定命令行中后续正则表达式所使用的正则表达式方言。
- 操作符Operators运算符将表达式中的其他项连接起来。例如它们包括`-o`(表示逻辑或)和`-a`(表示逻辑与)。如果缺少运算符,则默认使用`-a`。
## 表达式选项
### 测试选项
```shell
-amin<分钟>:查找在指定时间曾被存取过的文件或目录,单位以分钟计算;
-anewer<参考文件或目录>:查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录;
@ -22,65 +47,379 @@ find(选项)(参数)
-cmin<分钟>:查找在指定时间之时被更改过的文件或目录;
-cnewer<参考文件或目录>查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录;
-ctime<24小时数>查找在指定时间之时被更改的文件或目录单位以24小时计算
-daystart从本日开始计算时间
-depth从指定目录下最深层的子目录开始查找
-empty寻找文件大小为0 Byte的文件或目录下没有任何子目录或文件的空目录
-exec<执行指令>假设find指令的回传值为True就执行该指令
-executable 匹配当前用户可执行的文件和可搜索的目录。
-false将find指令的回传值皆设为False
-fls<列表文件>:此参数的效果和指定“-ls”参数类似但会把结果保存为指定的列表文件
-follow排除符号连接
-fprint<列表文件>:此参数的效果和指定“-print”参数类似但会把结果保存成指定的列表文件
-fprint0<列表文件>:此参数的效果和指定“-print0”参数类似但会把结果保存成指定的列表文件
-fprintf<列表文件><输出格式>:此参数的效果和指定“-printf”参数类似但会把结果保存成指定的列表文件
-fstype<文件系统类型>:只寻找该文件系统类型下的文件或目录;
-gid<群组识别码>:查找符合指定之群组识别码的文件或目录;
-group<群组名称>:查找符合指定之群组名称的文件或目录;
-help或--help在线帮助
-ilname<范本样式>:此参数的效果和指定“-lname”参数类似但忽略字符大小写的差别
-iname<范本样式>:此参数的效果和指定“-name”参数类似但忽略字符大小写的差别
-inum<inode编号>查找符合指定的inode编号的文件或目录
-ipath<范本样式>:此参数的效果和指定“-path”参数类似但忽略字符大小写的差别
-iregex<范本样式>:此参数的效果和指定“-regexe”参数类似但忽略字符大小写的差别
-iwholename 模式参见`-ipath`。此选项的可移植性较`-ipath`差。
-links<连接数目>:查找符合指定的硬连接数目的文件或目录;
-lname<范本样式>:指定字符串作为寻找符号连接的范本样式;
-ls假设find指令的回传值为True就将文件或目录名称列出到标准输出
-maxdepth<目录层级>:设置最大目录层级;
-mindepth<目录层级>:设置最小目录层级;
-mmin<分钟>:查找在指定时间曾被更改过的文件或目录,单位以分钟计算;
-mount此参数的效果和指定“-xdev”相同
-mtime<24小时数>查找在指定时间曾被更改过的文件或目录单位以24小时计算
-name<范本样式>:指定字符串作为寻找文件或目录的范本样式;
-newer<参考文件或目录>:查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录;
-newerXY<引用>:如果正在考虑的文件的时间戳 X 比文件引用的时间戳 Y 更新则成功。
-nogroup找出不属于本地主机群组识别码的文件或目录
-noleaf不去考虑目录至少需拥有两个硬连接存在
-nouser找出不属于本地主机用户识别码的文件或目录
-ok<执行指令>:此参数的效果和指定“-exec”类似但在执行指令之前会先询问用户若回答“y”或“Y”则放弃执行命令
-path<范本样式>:指定字符串作为寻找目录的范本样式;
-perm<权限数值>:查找符合指定的权限数值的文件或目录;
-print假设find指令的回传值为True就将文件或目录名称列出到标准输出。格式为每列一个名称每个名称前皆有“./”字符串;
-print0假设find指令的回传值为True就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行
-printf<输出格式>假设find指令的回传值为True就将文件或目录名称列出到标准输出。格式可以自行指定
-prune不寻找字符串作为寻找文件或目录的范本样式;
-readable匹配当前用户可读的文件
-regex<范本样式>:指定字符串作为寻找文件或目录的范本样式;
-samefile 名称 文件与名称指向相同的 inode。
-size<文件大小>:查找符合指定的文件大小的文件;
-true将find指令的回传值皆设为True
-type<文件类型>:只寻找符合指定的文件类型的文件;
-uid<用户识别码>:查找符合指定的用户识别码的文件或目录;
-used<日数>:查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算;
-user<拥有者名称>:查找符和指定的拥有者名称的文件或目录;
-version或——version显示版本信息
-xdev将范围局限在先行的文件系统中
-writable匹配当前用户可写入的文件。
-xtype<文件类型>:此参数的效果和指定“-type”参数类似差别在于它针对符号连接检查。
-context<表达式>:仅限 SELinux。文件的安全上下文与全局模式匹配
```
### 参数
### 操作选项
起始目录:查找文件的起始目录。
#### -delete 删除文件或目录。
> :warning:警告find 命令会将命令行作为表达式进行解析,因此将`-delete`放在首位会将指定的起始点下的**所有内容删除**。且`-delete`操作无法删除一个目录,除非它是空的。
### 实例
##### *无参数*
##### 描述
如果删除成功则返回真。若删除失败,将显示错误消息,并且 find 最终退出时的状态码将为非零。
##### 相关选项
- **-depth**:在命令行中使用`-delete`操作会自动启用`-depth`选项。为了避免意外情况,通常最好在早期的**Tests选项**中**明确使用**`-depth`选项。
- **-prune**:由于`-depth`会使`-prune`失效,因此`-delete`操作无法与`-prune`有效结合使用。通常,用户可能希望在实际删除操作前,先用带有`-print`的查找命令行进行测试,以确保在添加`-delete`进行实际删除时不会出现意外结果。
- **-ignore_readdir_race**`-delete`与此选项一起使用时find 会忽略自父目录读取以来文件已消失的情况下`-delete`操作的错误:它不会输出错误诊断,不会将退出代码更改为非零,并且`-delete`操作的返回代码将为真。
#### -exec 执行命令
> :warning:警告:使用`-exec`操作存在不可避免的安全问题,应改用`-execdir`选项。
##### 参数
`command ;``command {} +`
##### 描述
如果返回状态为 0则结果为真。**注意**find 命令会将**所有后续参数**视为`command`的参数,直到遇到包含`;`的参数为止。字符串`{}`会在`command`的参数中所有出现的位置被替换为当前正在处理的文件名,而不仅仅是在它单独出现的参数中,这与某些版本的 find 不同。这两种结构可能需要使用反斜杠`\`或引号来转义,以防止被 shell 扩展。指定的命令会为每个匹配的文件运行一次。命令在起始目录中执行。
#### -execdir 在包含匹配文件的子目录中执行命令
##### 参数
`command ;` | `command {} +`
##### 描述
类似于`-exec`,但指定的`command`会在包含匹配文件的**子目录中运行**而非find的起始点目录。与`-exec`一样如果从shell调用find`{}`应加引号。这是一种更安全的调用`command`方式,因为它避免了在解析匹配文件路径时出现的竞争条件。与`-exec`操作类似,`+`形式的`-execdir`会构建一个命令行来处理多个匹配文件,但任何给定的`command`调用只会列出存在于同一子目录中的文件。如果使用此选项,必须确保 PATH 环境变量未引用`.`,否则攻击者可以通过在您将运行`-execdir`的目录中留下一个适当命名的文件来运行任何命令。同样PATH 中的条目**不应为空**或**非绝对目录名**。如果使用`+`形式的任何调用以非零值作为退出状态返回,则 find 也会返回非零退出状态。如果 find 遇到错误,有时会导致立即退出,**因此某些待处理的command可能根本不会运行**。 操作结果取决于使用的是`+`还是`;`变体。`-execdir command {} + `总是返回真,而 `-execdir command {} ;`仅在命令返回 0 时返回真。
#### -fls 创建文件并将结果写入文件
##### 参数
`file`
##### 描述
此选项始终返回真。`-fls`类似于`-ls`和`-fprint`,但`-fls`会将结果写入文件中。无论谓词是否匹配,输出文件始终会被创建。有关文件名中特殊字符处理的信息,请参阅“特殊文件名处理”部分。
#### -fprint 将完整文件名打印到指定文件中
##### 参数
`file`
##### 描述
此选项始终返回真。若运行 find 时`file`不存在,则创建该`file`;若`file`已存在,则截断其内容。文件名`/dev/stdout`和`/dev/stderr`有特殊处理,分别指向标准输出和标准错误输出。即使谓词从未匹配,输出文件也会始终创建。
#### -fprint0
##### 参数
`file`
##### 描述
此选项始终返回真。类似于`-print0`,但将输出写入文件;类似于`-fprint`。即使谓词从未匹配,输出文件也始终会被创建。
#### -fprintf
##### 参数
`file`
##### 描述
此选项始终返回真。类似于`-printf`,但将输出写入文件;类似于`-fprint`,即使谓词从未匹配,输出文件也会始终创建。
#### -ls 列出当前文件并输出到标准输出
##### *无参数*
##### 描述
此选项始终返回真。以`ls -dils`格式列出当前文件并输出到标准输出。块计数为 1 KB 块,除非设置了环境变量 POSIXLY_CORRECT此时使用 512 字节块。
#### -ok 执行命令前询问用户
##### 参数
`command ;`
##### 描述
类似于`-exec`,但首先会询问用户。如果用户同意,则运行该命令;否则仅返回 false。若运行该命令其标准输入将被重定向至`/dev/null`。对提示的响应会与一对正则表达式进行匹配以确定其为肯定或否定回答。若设置POSIXLY_CORRECT 环境变量,则该正则表达式从系统获取;否则,从 find 的消息翻译中获取。如果系统没有合适的定义,将使用 find 自身的定义。无论哪种情况,正则表达式本身的解释都会受到环境变量 LC_CTYPE字符类和 LC_COLLATE字符范围和等价类的影响。
##### 相关选项
- **-files0-from**:不能与`-ok`同时指定。
#### -okdir
##### 参数
`command ;`
##### 描述
类似于`-execdir`,但在执行前会以与`-ok`相同的方式询问用户。如果用户不同意,则直接返回 false。如果命令被执行其标准输入将从`/dev/null`重定向。
##### 相关选项
- **-files0-from**:不能与`-okdir`同时指定。
#### -print 打印完整文件名,后跟一个换行符
##### *无参数*
##### 描述
此选项始终返回真。如果你将 find 的输出通过管道传输到另一个程序,并且你正在搜索的文件可能包含换行符,那么应该考虑使用`-print0`而不是`-print`。
#### -print0 打印完整文件名,后跟一个空字符
##### *无参数*
##### 描述
此选项始终返回真。包含换行符或其他类型空白字符的文件名能被正确解析,以便处理 find 输出的程序能正确理解。此选项对应于`xargs`的`-0`选项。
#### -printf 打印格式
##### 参数
`format`
可用的转义字符和指令包括:
- \a 警报。
- \b 退格键。
- \c 立即停止打印并清空输出。
- \f 换页。
- \n 换行。
- \r 回车符。
- \t 水平制表符。
- \v 垂直制表符。
- \0 空字符。
- \\\ 一个字面的反斜杠`\`。
- \NNN 字符,其 ASCII 码为 NNN八进制
- A 一个反斜杠字符`\`后跟任何其他字符,都会被视为普通字符,因此它们都会被打印出来。
- %% 一个字面的百分号。
- %a 文件的最后访问时间,格式为 C 语言 ctime(3)函数返回的样式。
.....更多内容待补充
##### 描述
*暂无*
#### -prune 如果文件是目录,则不进入该目录
##### *无参数*
##### 描述
此选项始终返回真。
##### 相关选项
- **-depth**:如果指定了`-depth`,那么`-prune`将无效。
- **-delete**:因为`-delete`隐含了`-depth`,所以不能有效地同时使用两者。
#### -quit 立即退出
##### *无参数*
##### 描述
如果没有发生错误,则返回值为零。这与`-prune `不同,因为`-prune`仅适用于被修剪目录的内容,而`-quit`则使 find 立即停止。不会有任何子进程继续运行。在程序退出之前,任何通过`-exec ... +`或`-execdir ... +`构建的命令行都会被调用。执行`-quit`后,命令行中指定的文件将不再被处理。例如,`find /tmp/foo /tmp/bar -print -quit`将仅打印 `/tmp/foo`。`-quit`的一个常见用途是在找到所需内容后停止搜索文件系统。
### 全局选项
始终返回真值。全局选项对命令行中较早出现的测试也会生效。为避免混淆,全局选项应在命令行上列出**起始点之后、第一个测试选项、位置选项或操作选项之前指定**。若在其他位置指定全局选项find 会发出警告消息,说明这可能引起混淆。
> 全局选项出现在起始点列表之后,因此与例如`-L` 这样的选项不属于同一类别。
#### -d `-depth`的同义词
##### *无参数*
##### 描述
仅用于与 FreeBSD、NetBSD、MacOS X 和 OpenBSD 兼容。
#### -depth 遍历级别
##### 参数
`levels`
##### 描述
在处理目录本身之前,先处理目录中的内容。`-delete`操作也隐含了`-depth`。
#### -files0-from 从文件中读取起始点,而非通过命令行获取。
##### 参数
`file`
##### 描述
使用此选项可以安全地给 find 命令传递任意数量的起始点。使用此选项和在命令行中传递起始点**是互斥的**,因此不允许同时进行。文件参数是强制性的。文件中的起始点必须用 ASCII NUL 字符分隔。两个连续的 NUL 字符,即带有零长度文件名的起始点是不允许的,这将导致错误诊断,并随后产生非零退出码。
与标准调用不同在标准调用中如果没有传递路径参数find 会默认将当前目录作为起始点。起始点的处理方式与其他情况相同例如find 命令会递归进入子目录,除非另有阻止。若要仅处理起始点,可以额外传递`-maxdepth 0`参数。
**其他说明**如果一个文件在输入文件中被列出多次则其是否会被多次访问未作规定。如果在查找操作期间文件被修改结果同样未作规定。最后find 退出时(无论是通过`-quit`还是其他方式),命名文件中的查找位置也未作规定。此处**未作规定**意味着它**可能有效也可能无效****或者不做任何特定的事情**,并且该行为可能因平台或 findutils 版本而异。
> :bulb:可以使用`-files0-from`**从标准输入流中读取起始点列表**,例如从管道中读取。在这种情况下,不允许使用`-ok`和`-okdir`操作,因为它们会干扰从标准输入读取以获取用户确认。
> :warning:警告如果给定文件为空find 不会处理任何起始点,因此在解析完程序参数后会立即退出。
#### -help 和 --help 打印 find 命令行用法的摘要并退出。
##### *无参数*
##### 描述
*无描述*
#### -ignore_readdir_race
##### *无参数*
##### 描述
通常情况下,当 find 无法对文件进行状态检查stat会发出错误消息。如果您**启用此选项**,并且在 find 从目录读取文件名,到尝试进行状态检查**之间的时间内文件被删除**,则不会发出任何错误消息。这也适用于命令行中指定的文件或目录。此选项在命令行读取时生效,这意味着您不能在文件系统的某部分启用此选项,而在另一部分禁用它(如果需要这样做,您需要发出两个 find 命令,一个启用选项,一个不启用)。此外,使用`-ignore_readdir_race`选项时如果在读取父目录后文件已消失find 命令将忽略`-delete`操作的错误:它不会输出错误诊断信息,并且`-delete`操作的返回码将为真。
#### -maxdepth 最大遍历级别
##### 参数
`levels`
##### 描述
最多向下遍历 levels 级(一个非负整数)目录层级。使用`-maxdepth 0`表示**仅对起始点本身**应用测试和操作。
#### -mindepth 最小遍历级别
##### 参数
`levels`
##### 描述
在小于指定级别(非负整数)的层级上不执行任何测试或操作。使用`-mindepth 1`表示处理**除起始点外的所有文件**。
#### -mount 不在其他文件系统中下降目录
##### *无参数*
##### 描述
这是`-xdev`的替代名称,用于与其他一些版本的 find 兼容。
#### -noignore_readdir_race
##### *无参数*
##### 描述
关闭了`-ignore_readdir_race`的效果。
#### -noleaf 不进行优化。
##### *无参数*
##### 描述
不通过假设目录包含比其硬链接数少 2 个子目录来进行优化。在搜索不遵循 Unix 目录链接惯例的文件系统时,需要此选项,例如 CD-ROM、MS-DOS 文件系统或 AFS 卷挂载点。在正常的 Unix 文件系统上,每个目录至少有 2 个硬链接:其名称及其`.`条目。此外,其子目录(如果有)各自有一个指向该目录的`..`条目。当 find 检查一个目录时,在它已经统计了比目录链接数少 2 个子目录之后,它知道该目录中的其余条目是非目录(目录树中的“叶”文件)。如果只需要检查文件的名称,则无需对其进行状态检查;这可以显著提高搜索速度。
#### -version 和 --version 打印 find 的版本号并退出。
##### *无参数*
##### 描述
*无描述*
#### -xdev 不进入其他文件系统的目录。
##### *无参数*
##### 描述
*无描述*
### 位置选项
始终返回真值。它们仅影响命令行中后续的测试。
#### -daystart 从今天开始
> 用于 `-amin`、`-atime`、`-cmin`、`-ctime`、`-mmin` 和 `-mtime`
##### *无参数*
##### 描述
从今天开始而非从 24 小时前开始。此选项仅影响命令行中后续出现的测试。
#### ~~-follow~~ 解引用符号链接。
##### *无参数*
##### 描述
**已弃用,请改用`-L`选项**。隐含`-noleaf`。`-follow`选项仅影响命令行中出现在其后的那些测试。除非已指定`-H`或`-L`选项,否则`-follow`选项的位置会改变`-newer`谓词的行为;作为`-newer`参数列出的任何文件,如果它们是符号链接,则会被解引用。同样的情况适用于`-newerXY`、`-anewer`和`-cnewer`。类似地,`-type `谓词将始终匹配符号链接所指向的文件类型,而非链接本身。使用`-follow`会导致 `-lname`和`-ilname`谓词始终返回 false。
#### -regextype 更改正则表达式语法
##### 参数
`type`
##### 描述
更改`-regex`和`-iregex`测试在命令行后续部分所理解的正则表达式语法。要查看已知的正则表达式类型,请使用`-regextype help`。Texinfo 文档解释了各种正则表达式类型的含义及其差异。如果您不使用此选项find 的行为如同已指定正则表达式类型为`emacs`。
#### -warn 和 -nowarn 开启或关闭警告消息。
##### *无参数*
##### 描述
这些警告仅适用于命令行使用,不适用于 find 在搜索目录时可能遇到的情况。默认行为是:如果标准输入是`tty`,则对应`-warn`;否则对应`-nowarn`。如果产生与命令行使用相关的警告消息find 的退出状态不受影响。如果设置了 POSIXLY_CORRECT 环境变量,并且也使用了`-warn`,则未指定哪些(如果有)警告会被激活。
### 运算符选项
运算符按优先级递减顺序列出:
- `(expr)` 强制优先级。由于括号对 shell 有特殊含义,通常需要对它们进行引用。许多示例为此使用了反斜杠:`\(...\)` 而非 `(...)`。
- `! expr` 若表达式为假则结果为真(取反)。此字符通常也需要防止被 shell 解释。
> :bulb:提示:当`-a`隐式指定(例如两个测试之间没有显式运算符)或显式指定时,其优先级高于`-o`。例如,`find . -name foo -o -name bar -print`永远不会打印`foo`。
#### -not
##### 参数
`expr`
##### 描述
等同于`! expr`,但不符合 POSIX 标准。
#### -a
##### 参数
`expr1` -a `expr2`
##### 描述
两个连续的表达式被视为隐含地用`-a`连接;如果`expr1`为假,则不评估`expr2`。等同于`expr1 expr2`。
#### -and
##### 参数
`expr1` -and `expr2`
##### 描述
与`-a`相同。但不符合 POSIX 标准。
#### -o
##### 参数
`expr1` -o `expr2`
##### 描述
`expr1`和`expr2`始终都会被评估。`expr1`的值会被丢弃;列表的值即为`expr2`的值。逗号运算符(`,`)在搜索多种不同类型的事物时非常有用,但只会遍历文件系统层次结构一次。`-fprintf`动作可用于将各种匹配项列出到多个不同的输出文件中。若`expr1`为真,则不评估`expr2`。
#### -or
##### 参数
`expr1` -or `expr2`
##### 描述
与`-o`相同。但不符合 POSIX 标准。
## 例子
当前目录搜索所有文件,且文件内容包含 “140.206.111.111”
```shell
# 当前目录搜索所有文件,文件内容 包含 “140.206.111.111” 的内容
find . -type f -name "*" | xargs grep "140.206.111.111"
```