为什么“find -exec cmd {} +”需要以“{} +”结尾?

Mar*_*oij 12 find history posix

前言:我理解-exec {} \;&之间的区别-exec {} +。我也没有问题,因为这样,我只是好奇的语义find


-exec+而不是结束参数时;,我们需要以 结束{} +,例如:

# FreeBSD find
$ find . -type f -exec cp {} /tmp +
find: -exec: no terminating ";" or "+"

# GNU find is even more cryptic:
$ find: missing argument to `-exec'
Run Code Online (Sandbox Code Playgroud)

;在这些示例中使用而不是+工作正常(但显然做了其他事情)。

POSIX

-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +

... 只有紧跟在仅包含两个字符 " {}"的参数之后的 <plus-sign>应标点主表达式的结尾。<加号> 的其他用途不应被视为特殊用途。

换句话说,当使用 时+,命令需要以 结尾{} +

为什么是这样?为什么只有与+而不是;?起初我想也许是为了避免与包含 a 的文件名发生冲突+,但带有 a 的文件名;似乎工作正常?我发现很难相信这个限制是任意的......

Gil*_*il' 6

POSIX 规范中给出的基本原理是:

采用的"-exec ... {} +"语法是 IEEE PASC 解释 1003.2 #210 的结果。应该注意的是,这是对 ISO/IEC 9899:1999 标准的不兼容更改。例如,以下命令打印所有文件,'-'如果它们是常规文件,则在其名称后带有 a ,'+'否则打印:

find / -type f -exec echo {} - ';' -o -exec echo {} + ';'
Run Code Online (Sandbox Code Playgroud)

这种变化使这样的用法无效。尽管以前的标准声明这种用法可行,但实际上很多人不支持它,标准开发人员认为现在声明这是不允许的更好。

PASC 解释 1003.2 #210更详细地介绍了-exec … {} +. 在被 POSIX 采用之前,它存在于几个 Unix 系统上;缺陷报告将其追溯到SVR4(它在很大程度上没有记录)。缺陷报告证明不兼容的更改在实践中几乎没有影响:

请注意,只有紧跟在“{}”之后的“+”才被视为特殊的。这最大限度地减少了现有使用“+”作为“-exec”参数的问题的可能性。

尽管添加对 的支持-exec … {} +会破坏一些符合要求的应用程序,例如上面的示例,但这些应用程序比-exec … {} … +允许的要少。

也许,限制{}为最后一个参数的另一个原因是易于实现。如果{}允许参数列表中的任何位置为-exec,则find程序必须通过复制静态参数,然后是变量部分,然后是另一个静态部分来构建命令行。这将使构建参数列表和考虑大小限制变得更加困难。难度很小,但实施者喜欢偷工减料。支持多个可替代的实例{}(如果-exec {} foo +要工作,从逻辑上讲-exec {} foo {} +也是如此)会困难得多。