将括号{}用作命令及其选项的参数的用法


11

例子

我最近发现了一些示例,这些示例使用成对的封闭括号{}作为命令甚至其选项的参数,而在括号之间没有任何东西:

cat foo | xargs -I{} echo {}

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

没有文件

我的问题是我无法在GNU Bash手册中找到描述上述情况{}下用法的文档。

我不认为这是参数扩展,因为在参数扩展中必须在括起来的花括号之前加一个美元符号,例如${}

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

它也不能作为命令分组,因为{}它用作参数。

问题

  1. {}一般而言,一对封闭的括号作为接受它的任何命令的参数甚至意味着什么?

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


某些命令具有此选项{}-意味着targets要执行find命令,即删除/ rm找到文件。
Tuyen Pham

Answers:


16

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

man find

-exec 命令 ;

执行命令 ; 如果返回0状态,则为true。以下所有要查找的参数都将作为命令的参数,直到;遇到由组成的参数。该字符串{}会被当前文件名替换,该文件名会在命令参数中出现的所有位置处进行处理,而不仅仅是在单独存在的参数中(如在某些版本的中)find。这两种构造都可能需要转义(带有\)或加引号,以防止它们被外壳扩展。有关使用该-exec选项的示例,请参见“示例”部分。指定 命令每个匹配的文件运行一次。该命令在起始目录中执行。围绕操作的使用存在不可避免的安全问题-exec 。您应该改用该-execdir选项。

-exec 命令 {} +

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

-execdir 命令 ;

-execdir 命令 {} +

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

man xargs

-I replace-str

将初始参数中出现的replace-str替换为从标准输入中读取的名称。同样,未加引号的空格也不会终止输入项目。相反,分隔符是换行符。表示-x-L 1

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

此选项的代名词-I顶替-STR如果更换-STR指定的。如果缺少replace-str参数,则效果与相同-I{}。不建议使用此选项;使用-I代替。

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

man bash

{ 清单; }

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

为了强调:list必须以换行符或分号终止


1
谢谢!我很烦恼的是,无论谁写的书,都man xargs没有费心去解释{}真正的含义,作者也没有(没有双关语意)将读者重定向到-exec的手册页中的解释find
Niko Gambt

@NikoGambt -我同情...
天衣

5
@NikoGambt好吧,{}对xargs并没有任何意义,只是-i的默认值已弃用。我不确定除此之外还需要什么解释。在您发布的示例中,它可能已经是xargs -Iab echo ab; 这是一个完全任意的选择。
Random832 '19

@ Random832在使用进行了更多测试之后-I,我现在了解了该选项的实际作用。是的,{}正如您所说,是任意的。我只是被这个解释弄糊涂了If the replace-str argument is missing, the effect is the same as -I{}。如果-I不带参数与相同-I{}cat foo | xargs -I echo {}则将产生与运行相同的结果cat foo | xargs -I{} echo {}。但是,它们并不相同。前者是一个错误,更让我感到困惑的是错误消息xargs: {}: No such file or directory,但这仅仅是由于实现。
Niko Gambt

1
@NikoGambt -I(大写字母I)不能在没有参数的情况下运行。的论据-Iecho。这是-I和之间的主要区别-i(以及-i被弃用的原因,因为带有非必需参数的选项很少见且令人困惑)
Random832 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.