Shell 使用选项+;执行另一个find命令时,为什么find会抱怨;

Shell 使用选项+;执行另一个find命令时,为什么find会抱怨;,shell,find,command-line-arguments,Shell,Find,Command Line Arguments,我读过,但不明白为什么。 我知道这个问题中的示例命令不是很有用,这只是一个示例命令 尝试运行以下命令: $ find -type d -exec find {} -ls + -exec echo {} + find: Only one instance of {} is supported with -exec ... + 在我看来,打印的错误是不正确的,因为我的命令由两个-exec组成,每个都有自己的final+ find -type d -exec find {} -ls + -exec

我读过,但不明白为什么。
我知道这个问题中的示例命令不是很有用,这只是一个示例命令


尝试运行以下命令:

$ find -type d -exec find {} -ls + -exec echo {} +
find: Only one instance of {} is supported with -exec ... +
在我看来,打印的错误是不正确的,因为我的命令由两个
-exec
组成,每个都有自己的final
+

find -type d -exec find {} -ls + -exec echo {} +
             <-----------------> <------------->
                 First command    Second command
当然,一种解决方法是用
\”替换
+
。但是我想知道为什么在上面的两个例子中会出现这些错误消息???请同时提供优雅的解决方案:-)

有关信息,我正在Ubuntu 16.10和bash上使用
find

$ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2) 
$find--version
find(GNU findutils)4.7.0-git
版权所有(C)2016免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本。
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。
作者:埃里克·B·德克、詹姆斯·扬曼和凯文·达利。
启用功能:D_类型O_无跟随(启用)叶优化FTS(FTS_CWDFD)CBO(级别=2)

-exec
与终止符
+
一起使用时(与
\;
相反):

  • 给定的
    -exec
    操作仅支持占位符
    {}
    和的单个实例
  • 只有一个实例必须放在最后,就在
    +
    之前
因此,由于传递给
-exec的
find
命令+总是在
{}
之后需要参数,因此无法工作

换句话说:使用
-exec+
,则不能调用任何命令,该命令要求您在
{}
表示的文件名列表之后传递参数

虽然错误消息可能没有帮助,但这些限制有一个很好的原因:
由于(依赖于平台)对命令行长度的限制,
-exec+
不能保证所有文件名都可以传递给指定命令的单个调用;与
xargs
一样,列表可能因此必须进行分区以执行多个调用(尽可能少)。考虑到这种可能性:如果允许在
{}
之后放置参数,那么在必须进行多个调用的情况下(将这些参数传递给每个调用?仅传递给最后一个调用?)如何处理这些参数的概念性问题,对此没有明确的答案。
这些都是我自己的推论——如果有什么不正确/应该添加,一定要让我知道

正如您在问题中所暗示的,这些限制不适用于
-exec…\
使用终止符
\
使
find
对每个匹配的文件调用一次命令,以便
{}
扩展为单个文件名,在这种情况下,您可以在命令的任何位置自由放置
{}
,可能多次。
相比之下,
-exec+
,使
find
一次(通常)将所有匹配的文件名(
{}
展开为文件名列表)传递给(通常)命令的单个整体调用。
根据具体命令,使用
\
代替
+
可能是一种可行的解决方法,但它具有重要的性能影响
:对于大型输入集,每个文件名创建一次外部进程和整个单个进程之间的差异将非常明显。


至于错误信息:


您想要成为两个
-exec
操作的内容被解析为一个,因为
find
会一直解析,直到它找到
{}
,紧接着是
+
。谢谢

只有紧跟在仅包含两个字符“{}”的参数之后的a才能标点主表达式的结尾。其他用途不应视为特殊用途

当解释为单个操作时,它现在包含两个
{}
实例,而
+
不支持这些实例,因此会出现错误消息(总的来说,这是令人困惑的)


此错误源于
{}
不是终止符
+
之前的最后一个参数,这意味着
+
未被识别为操作的终止符,因此整个操作在语法上无效


不幸的是,错误消息令人困惑地表明参数(要执行的命令)丢失-将其称为unterminated更有意义。

-exec
与终止符
+
一起使用时(与
\;
相反):

  • 给定的
    -exec
    操作仅支持占位符
    {}
    和的单个实例
  • 只有一个实例必须放在最后,就在
    +
    之前
因此,由于传递给
-exec的
find
命令+总是在
{}
之后需要参数,因此无法工作

换句话说:使用
-exec+
,则不能调用任何命令,该命令要求您在
{}
表示的文件名列表之后传递参数

虽然错误消息可能没有帮助,但这些限制有一个很好的原因:
由于(依赖于平台)对命令行长度的限制,
-exec+
不能保证所有文件名都可以传递给指定命令的单个调用;与
xargs
一样,列表可能因此必须进行分区以执行多个调用(尽可能少)。考虑到这种可能性:如果允许在
{}
之后放置参数,那么在必须执行多个调用的情况下,将出现如何处理这些参数的概念性问题
$ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2) 
$ find -type d -exec find {} -ls + -exec echo {} +
find: Only one instance of {} is supported with -exec ... +
$ find -type d -exec find {} -ls +
find: missing argument to `-exec'