find -exec command {} + 的命令行是如何构建的

Can*_*low 5 command-line find

我发现手册解释find有点不清楚。

“但是命令行是通过在末尾附加每个选定的文件来构建的;命令的总调用次数将远小于匹配文件的数量”是什么意思?为什么是这样?

下面是正文 man find

-exec 命令 {} +

这个-exec动作的变体在选定的文件上运行指定的命令,但命令行是通过在末尾附加每个选定的文件名来构建的;命令的总调用次数将远小于匹配文件的数量。命令行的构建方式与xargs构建其命令行的方式大致相同。命令中只允许有一个“{}”实例。该命令在起始目录中执行。

Joh*_*024 5

“但是命令行是通过在最后附加每个选定的文件来构建的;命令的总调用次数将远小于匹配文件的数量”是什么意思?这是为什么?

让我们创建一些示例文件:

touch {1..5}.txt
Run Code Online (Sandbox Code Playgroud)

首先,让我们运行一个 find 命令:

$ find . -exec echo my files are: {} +
my files are: . ./1.txt ./5.txt ./4.txt ./3.txt ./2.txt
Run Code Online (Sandbox Code Playgroud)

如您所见,{}已替换为find找到的所有文件的列表。在这个例子中,我们有六个匹配的文件但echo只运行了一次。

请注意,shell 对它们在单个命令行上可接受的字符数有限制。 find知道这一点,如果有太多的文件放在一个命令行上,findecho使用不同的文件多次运行,直到处理完所有文件名。这就是为什么“命令的调用次数将远小于匹配文件的数量”。

让我们通过在我们的目录中创建许多文件来测试这一点:

touch this_is_a_long_file_name{1..10000}.txt
Run Code Online (Sandbox Code Playgroud)

现在,让我们执行一个 find 命令:

$ find . -exec bash -c 'echo $# files on this command line' _ {} +
3756 files on this command line
3754 files on this command line
2491 files on this command line
Run Code Online (Sandbox Code Playgroud)

如您所见,即使这个目录有超过 10,000 个文件,exec 命令也只运行了 3 次。