在文档中,我看到了两种用法:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
在文档中,我看到了两种用法:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
Answers:
为bash
外壳,'{}'
且{}
可互换。并非所有shell(例如fish
)都并非如此。
将参数用单引号明确表示应将花括号发送到find
。根据用法,bash shell有时会替换大括号中的内容。
如下所示,bash不会替换空括号,并且将它们传递给命令。对于find
命令来说,没关系。
$ echo {}
{}
$ echo {1}
{1}
$ echo {1,3}
1 3
$ echo '{1,3}'
{1,3}
" 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"
(良好的习惯,首先要确保您使用正确的方式,即使您碰巧(总是?)处于允许模棱两可的系统上)
在几乎所有的shell解释器可用的情况下,'{}'
和之间绝对没有区别{}
。
单引号通常用于防止嵌入的字符串被其他东西替代,例如:
'a b'
是单个三个字符的参数,不带引号的是两个单个字符的参数'$b'
是字面上的美元符号,后跟字母b,不带引号就是b变量包含的内容,如果未设置,则可能不包含任何引号'!!'
是乱写的感叹号,不加引号,带有一些交互式外壳,它们会扩展到历史记录中的最后一条命令'*'
是一个乱码,没有引号,它将被当前目录中的非隐藏文件名列表取代。既不POSIX标准,也不是主流壳(sh
(伯恩)ksh
,bash
,ash
,dash
,zsh
,csh
,tcsh
)扩展{}
到别的东西,不需要引号。
但是,有一个名为的奇异外壳,fish
它恰好会扩展{}
为空字符串,例如:
> ps -p %self
PID TTY TIME CMD
5247 pts/1 00:00:00 fish
> echo a {} b '{}'
a b {}
这可能是GNU find
文档建议防止{}
使用引号或反斜杠进行解释的原因。
对于大多数用户(尤其是使用POSIX shell的用户)而言,没有什么区别。
根据GNU手册页的Example部分find
:
请注意,括号用单引号引起来,以防止其解释为shell脚本标点符号。
我认为GNU手册页的作者很谨慎,但我注意到并不是他们手册页中的所有示例都引用了花括号。官方GNU查找文档中的这些示例也省略了引用。
在POSIX / Single UNIX规范的示例中,当与该选项一起使用时,不引用大括号-exec
。
对于POSIX Shell, 仅当括号内包含特殊参数时才发生参数扩展,而空括号则不发生。
Bash外壳程序将括号扩展包含为(非便携式)功能,但是仅当括号中包含逗号或点时,才会扩展此类模式。Bash还将大括号用于命令分组,但是除非大括号内实际有一组命令,否则不会发生这种情况。
最后,我试图运行find -exec ls -l {} \;
的sh
,dash
并且tcsh
但这些炮弹扩大{}
到其他任何东西。正如其他人指出的那样,fish
shell会被{}
特殊对待,但这不是POSIX shell(它的创建者和用户认为这是一个优势)。它没有伤害引用括号谁不使用鱼外壳不应该感到内疚忽略他们,但懒惰的打字员。
'{}'
而不是{}
),以便他们的shell发送{}
给find命令而不对其进行解释(如上面提到的@ Charles-Duffy,如果您碰巧使用了fish的话) ,它将解释{}
但不会解释'{}'
,因此您需要在该shell上(以及在其他几个外壳上)使用后者。因此,请务必'{}'
避免被{}
这取决于您的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» «» «;»
作为一般建议,引用它永远不会感到痛苦。