该[命令是普通命令。尽管大多数shell都将其作为效率的内置组件提供,但它遵循了shell的常规语法规则。[与完全等效test,不同之处在于,最后一个参数[要求]为,test而不需要。
双括号[[ … ]]是特殊语法。之所以在ksh中引入了它们(几年后[),因为[正确使用可能会很麻烦,并且[[允许使用shell特殊字符添加一些不错的新东西。例如,你可以写
[[ $x = foo && $y = bar ]]
因为整个条件表达式是由shell解析,而[ $x = foo && $y = bar ]将首先分成两个命令[ $x = foo和$y = bar ]由分离的&&操作者。类似地,双括号使诸如模式匹配语法之类的功能成为可能,例如[[ $x == a* ]],测试start的值是否x以a; 在单括号中,这将扩展a*到名称列表a在当前目录中开头的文件列表。双括号首先在ksh中引入,仅在ksh,bash和zsh中可用。
与其他大多数地方一样,在单括号内,您需要在变量替换周围使用双引号,因为它们只是命令的参数(碰巧是[命令)。在双括号内,您不需要双引号,因为shell不会进行单词拆分或加修饰:它解析的是条件表达式,而不是命令。
但是[[ $var1 = "$var2" ]],如果要进行字节到字节的字符串比较,则需要在引号中做一个例外,否则$var2将是一种匹配的模式$var1。
您不能做的一件事[[ … ]]就是使用变量作为运算符。例如,这是完全合法的(但很少有用):
if [ -n "$reverse_sort" ]; then op=-gt; else op=-lt; fi
…
if [ "$x" "$op" "$y" ]; then …
在你的例子中
dir="/home/mazimi/VirtualBox VMs"
if [ -d ${dir} ]; then …
内的命令if是[与所述4个参数-d,/home/mazimi/VirtualBox,VMs和]。shell解析-d /home/mazimi/VirtualBox,然后不知道该怎么做VMs。您将需要防止单词分裂${dir}以获取格式正确的命令。
一般而言,除非知道要对结果执行单词拆分和遍历,否则始终在变量和命令替换周围使用双引号。不使用双引号安全的主要地方是:
- 在赋值中:(
foo=$bar但请注意,您确实需要export "foo=$bar"在数组赋值中或数组赋值中使用双引号,例如array=("$a" "$b"));
- 在一个
case声明:case $foo in …;
- 里面除了上的右侧双括号
=或==操作符(除非你想要模式匹配)[[ $x = "$y" ]]。
在所有这些中,使用双引号是正确的,因此您最好跳过高级规则并始终使用引号。