有什么区别
引号仅包围选项值
例如:
grep --file="grep pattern file.txt" *
与
选项名称和选项值用引号括起来
例如:
grep "--file=grep pattern file.txt" *
?
它们产生相同的结果。
有什么区别
引号仅包围选项值
例如:grep --file="grep pattern file.txt" *
与
选项名称和选项值用引号括起来
例如:grep "--file=grep pattern file.txt" *
?
它们产生相同的结果。
shell 中的引号和反斜杠用于消除某些字符的特殊性,以便将它们视为普通字符。
双引号的特殊之处在于它们仍然允许在其中进行扩展。或者换句话说,在它们之中
$
、\
、 和`
仍然是特殊的。它们还会影响这些扩展的执行方式。在该行中,shell 唯一的特殊字符是:
*
,它是一个通配模式运算符,并且这样一个字符的存在,当不在简单的命令行中引用时,会触发一种称为文件名生成或通配或路径名扩展(POSIX 措辞)的机制。其他字符在 shell 语法中没有特殊意义。
在这里,我们想要做的是让 shell 使用
/usr/bin/grep
这些参数执行该文件:grep
--file=grep pattern file.txt
所以我们确实想要:
*
被视为全局运算符并扩展到当前工作目录中的非隐藏文件。所以上面的那些字符一定不能被引用。
但是,我们希望将其中两个空格包含在传递给 的第二个参数中
grep
,因此必须将它们括起来。所以至少,我们需要:或者:
(显示不同的引用运算符)
在这里,我们只引用 shell 特有的 2 个字符,并且我们不希望将其视为这样。但我们也可以这样做:
并引用除我们希望 shell 特殊处理的字符之外的所有字符。
引用这些非特殊字符对 shell 没有任何影响。
在这里交替使用不同形式的引号将起到相同的作用。
鉴于命令和选项²名称很少包含 shell 特殊字符,因此习惯上不引用它们。你很少看到人们用
'ls' '-l'
of 代替ls -l
,所以这grep --file="the value"
是一种常见的现象,即使它与grep "--file=the value"
or相比没有什么区别grep --file=the" value"
。请参阅如何在 Unix shell 中像普通字符一样使用特殊字符?有关哪些字符是特殊的以及在各种 shell 中引用它们的方法的更多详细信息。
现在该命令仍然存在一些问题:
*
开头-
,它将被视为一个选项*
展开所有文件,无论其类型如何。其中包括目录、符号链接、fifo、设备。您可能只想查看常规类型的文件(或者可能符号链接到常规文件)--file
是一个GNU主义。标准等效项是-f
.*
仅扩展为一个文件,grep
则不会包含文件名以及匹配行。*
不匹配任何文件,在包括 bash(默认情况下)在内的一些 shell 中,*
将传递一个文字参数grep
(并且它可能会抱怨无法打开该名称的文件)。因此,在这里,您想使用 zsh shell 为例,并编写:
在哪里:
-f
用于代替--file
.--
标记选项的结束,这样即使它以 开头,后面的任何其他参数也不会被视为一个-
。/dev/null
至少grep
传递 2 个文件,保证它总是打印文件名。*(-.)
文件中使用so查找。如果不匹配任何内容,将因不匹配错误而中止,并且不运行 grep。grep
zsh
因为,我们传递
/dev/null
给grep
,所以我们还可以添加N
glob 限定符 (*(N-.)
) ,这会导致 glob 在没有匹配项时扩展为空,而不是报告错误,并且grep
只会查看内部/dev/null
(并且默默地失败)。1 请注意在 shell 语法中引用关键字,例如
while
,do
,if
,time
即使部分也会产生影响,因为它会阻止 shell 识别它们;类似地,'v'ar=value
将阻止 shell 将其视为变量赋值,因为'v'ar
它不是有效的变量名称(并且在解析语法后执行引号处理)。或者,如果您编写它们,或者除非您也有这些引用形式的别名(很少有 shell 允许您这样做),则您的foo
别名将不会扩展\foo
f'oo'
-?
²受 Microsoft 启发的实用程序有时会发现明显的例外。3 对于 GNU 来说
grep
,这也适用于其他参数,而不仅仅是第一个参数,因为 GNUgrep
(以及现在的一些其他类似 GNU 的实现)即使在非选项参数之后也接受选项。