man find

man find

例子

我最近发现了使用成对的大括号的示例{},在左大括号和右大括号之间没有任何内容,作为命令甚至选项的参数:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

无文档

我的问题是我找不到文档GNU Bash 手册{}描述了在上述示例中的上下文中的用法。

我不认为这是一个参数扩展,因为在参数扩展中,美元符号必须位于大括号之前,如 中所示${}

它不可能是一个大括号扩展要么,因为它采用 的形式{x..y[..incr]},其中xy不是可选的。

它也不能是一个命令分组或者,because{}被用作参数。

问题

  1. {}一般来说,一对大括号作为任何接受它的命令的参数意味着什么?

  2. 在哪里可以找到描述 as 参数用法的文档{}

答案1

这些大括号被 bash 保留;它们分别属于findxargs,并在其手册页中进行了描述。

man find

-exec 命令 ;

执行命令;如果返回 0 状态则为 true。 find 的所有以下参数都被视为命令的参数,直到;遇到由以下组成的参数。该字符串{}将被替换为在命令参数中出现的所有地方正在处理的当前文件名,而不仅仅是在单独的参数中,如某些版本的find.这两种结构可能都需要转义(用\)或引用,以保护它们免受 shell 的扩展。有关该选项的使用示例,请参阅示例部分-exec。指定的 命令对每个匹配的文件运行一次。该命令在起始目录中执行。该操作的使用存在不可避免的安全问题-exec ;你应该使用该-execdir选项。

-exec 命令 {} +

该操作的变体-exec运行指定的命令在选定的文件上,但命令行是通过在末尾附加每个选定的文件名来构建的;该命令的调用总数将远小于匹配的文件数。命令行的构建方式与xargs构建其命令行的方式大致相同。{}命令中只允许出现一个 的实例。该命令在起始目录中执行。如果find遇到错误,有时会导致立即退出,因此某些挂起的命令可能根本无法运行。这个变体-exec总是返回 true。

-execdir 命令 ;

-execdir 命令 {} +

与 类似 -exec,但指定的命令是从包含匹配文件的子目录运行的,该子目录通常不是您开始查找的目录。这是一种更安全的调用命令的方法,因为它避免了解析匹配文件的路径期间的竞争条件。与 -exec 操作一样, + 的形式 -execdir 将构建一个命令行来处理多个匹配的文件,但任何给定的命令调用都只会列出同一子目录中存在的文件。如果你使用这个选项,你必须确保你的$PATH环境变量没有引用.;否则,攻击者可以通过在您将运行的目录中保留适当命名的文件来运行他们喜欢的任何命令-execdir。这同样适用于其中的条目为$PATH空或不是绝对目录名称。如果find遇到错误,有时会导致立即退出,因此某些挂起的命令可能根本无法运行。操作的结果取决于是否正在使用 该操作+或变体;;-execdir 命令 {} +总是返回 true,而-execdir 命令 {} ;仅当以下情况时才返回 true命令返回 0。

man xargs

-I 替换-str

替换出现的替换-str在初始参数中,名称从标准输入读取。此外,不带引号的空格不会终止输入项;相反,分隔符是换行符。意味着-x-L 1

-i[替换-str], --replace[=替换-str]

该选项的同义词是-I替换-str如果替换-str已指定。如果替换-str缺少参数,效果与 相同-I{}。该选项已被弃用;代替使用-I

编辑:和这里为什么bash 忽略那些花括号:

man bash

{ 列表; }

列表 只是在当前 shell 环境中执行。 列表必须以换行符或分号终止。这称为组命令。返回状态是list的退出状态。请注意,与元字符不同,{}是保留字,并且必须出现在允许识别保留字的地方。由于它们不会导致断词,因此必须用空格或其他 shell 元字符将它们与列表分隔开。

为了强调:列表必须以换行符或分号结束

相关内容