在里面文档,我看到两种用法:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
答案1
对于bash
shell,'{}'
和{}
是可以互换的。但并非所有 shell 都是如此(例如fish
)。
将参数放在单引号中明确表示应将花括号发送到find
。根据用法,bash shell 有时会替换花括号的内容。
如下所示,bash 不会替换空括号,它们会传递给命令。对于命令来说find
,这并不重要。
$ echo {}
{}
$ echo {1}
{1}
$ echo {1,3}
1 3
$ echo '{1,3}'
{1,3}
答案2
'{}'
由于几乎所有的 shell 解释器都可用,因此和之间根本没有区别{}
。
单引号通常用于保护嵌入的字符串不被其他字符串替换,例如:
'a b'
是一个三个字符的参数,不加引号的话就是两个单字符参数'$b'
实际上是美元符号后跟字母 b,不带引号,即 b 变量包含的任何内容,如果未设置则可能为空'!!'
在没有引用的情况下是感叹号,并且在某些交互式 shell 中,它们会扩展为历史记录中的最后一条命令'*'
是一个文字星号,不加引号时它将被当前目录中非隐藏文件名列表替换。
由于 POSIX 标准和主流 shell((Bourne)、、、、、、、、)都不会扩展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 {}
find
这可能就是为什么 GNU文档建议{}
使用引号或反斜杠来防止解释的原因。
答案3
对于大多数用户(尤其是使用 POSIX shell 的用户)来说,没有区别。
根据 GNU 手册页的示例部分find
:
请注意,括号括在单引号中,以防止它们被解释为 shell 脚本标点符号。
我认为 GNU 手册页的作者过于谨慎,但我注意到,他们的手册页中并非所有示例都引用了括号。这些来自官方 GNU find 文档的示例也省略引用。
在里面来自 POSIX/单一 UNIX 规范的示例括号内是未引用与选项一起使用时-exec
。
使用 POSIX shell,参数扩展 仅当括号内有特殊参数时才会发生 - 但是不带空括号。
Bash shell 包括括号扩展作为(不可移植的)功能,但这种模式只会扩展当括号内有逗号或点时. Bash 还使用括号来命令分组,但除非确实存在是括号内的一组命令。
最后,我尝试find -exec ls -l {} \;
在 和 中运行sh
,dash
但tcsh
这些 shell 都没有将 扩展{}
为其他任何内容。正如其他人指出的那样,fish
shell 会特殊对待{}
,但这不是 POSIX shell(其创建者和用户认为这是一个优势)。它引用括号不会造成任何损害但是不使用 fish shell 的懒惰打字员不应该为省略它们而感到内疚。
答案4
这取决于你的 shell 语法。如有疑问,请回显!
运行此
echo '{}'
和这个。
echo {}
如果它们产生相同的输出,则您的 shell 的答案是肯定的。正如其他人所指出的,至少在 bash 中是肯定的,而在 fish 中是否定的。输出是您应该查阅给定命令的手册页的内容。
如果你想方便的话,你甚至可以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 {} \;
对 bash 来说意味着:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»
鱼类方面:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»
作为一般建议,引用永远不会有坏处。