find命令中“ {}”和{}之间的区别?


Answers:


24

bash外壳,'{}'{}可互换。并非所有shell(例如fish)都并非如此。

将参数用单引号明确表示应将花括号发送到find。根据用法,bash shell有时会替换大括号中的内容。

如下所示,bash不会替换空括号,并且将它们传递给命令。对于find命令来说,没关系。

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
与bash无关。与鱼无关紧要。
Charles Duffy 2015年

1
我将替换" are interchangeable"" are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"(良好的习惯,首先要确保您使用正确的方式,即使您碰巧(总是?)处于允许模棱两可的系统上)
Olivier Dulac 2015年

9

在几乎所有的shell解释器可用的情况下,'{}'和之间绝对没有区别{}

单引号通常用于防止嵌入的字符串被其他东西替代,例如:

  • 'a b' 是单个三个字符的参数,不带引号的是两个单个字符的参数
  • '$b' 是字面上的美元符号,后跟字母b,不带引号就是b变量包含的内容,如果未设置,则可能不包含任何引号
  • '!!' 是乱写的感叹号,不加引号,带有一些交互式外壳,它们会扩展到历史记录中的最后一条命令
  • '*' 是一个乱码,没有引号,它将被当前目录中的非隐藏文件名列表取代。

既不POSIX标准,也不是主流壳(sh(伯恩)kshbashashdashzshcshtcsh)扩展{}到别的东西,不需要引号。

但是,有一个名为的奇异外壳,fish它恰好会扩展{}为空字符串,例如:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

这可能是GNU find文档建议防止{}使用引号或反斜杠进行解释的原因。


9

对于大多数用户(尤其是使用POSIX shell的用户)而言,没有什么区别。

根据GNU手册页的Example部分find

请注意,括号用单引号引起来,以防止其解释为shell脚本标点符号。

我认为GNU手册页的作者很谨慎,但我注意到并不是他们手册页中的所有示例都引用了花括号。官方GNU查找文档中的这些示例也省略了引用。

POSIX / Single UNIX规范示例中,当与该选项一起使用时,不引用大括号-exec

对于POSIX Shell, 仅当括号内包含特殊参数时才发生参数扩展,而空括号则不发生

Bash外壳程序将括号扩展包含为(非便携式)功能,但是仅当括号中包含逗号或点时,才会扩展此类模式。Bash还将大括号用于命令分组,但是除非大括号内实际一组命令,否则不会发生这种情况。

最后,我试图运行find -exec ls -l {} \;shdash并且tcsh但这些炮弹扩大{}到其他任何东西。正如其他人指出的那样,fishshell会被{}特殊对待,但这不是POSIX shell(它的创建者和用户认为这是一个优势)。它没有伤害引用括号谁不使用鱼外壳不应该感到内疚忽略他们,但懒惰的打字员。


他们没有犯错,他们试图确保人们使用正确的方式(即使用'{}'而不是{}),以便他们的shell发送{}给find命令而不对其进行解释(如上面提到的@ Charles-Duffy,如果您碰巧使用了fish的话) ,它将解释{}但不会解释'{}',因此您需要在该shell上(以及在其他几个外壳上)使用后者。因此,请务必'{}'避免被{}
Olivier Dulac

6

这取决于您的Shell语法。如有疑问,请回声!

运行这个

echo '{}'

还有这个。

echo {}

如果它们产生相同的输出,那么您的shell的答案是肯定的。正如其他人指出的那样,在bash中至少会是“是”,而在鱼类中则不会。输出是您应查阅给定命令的手册页的内容。


如果您想方便使用,甚至echo可以在整个命令行前添加前缀,以查看shell实际调用的实际命令及其所有参数。但是请注意,包含命令加参数的列表是真正的字符串数组,每个字符串都可能为空或带有空格,但是echo将其模糊地打印为空格分隔的列表。

可以通过这个稍微冗长的echo命令(显示用guillemet引用的参数)来验证,

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

在命令行上输入

find 'My Documents and Settings' -type f -exec file {} \;

意味着要扑面而来:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

这在鱼中:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

作为一般建议,引用它永远不会感到痛苦。

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.