shell:使用双括号 [[ 进行测试,而单括号 [ 则不进行测试

shell:使用双括号 [[ 进行测试,而单括号 [ 则不进行测试

有这样一行简单的代码:

user@Host:~$ ls -> fileA fileB
user@Host:~$ [[ -d $dir_name ]] && rm * # $dir_name does not exist, empty variable
user@Host:~$ ls -> fileA fileB  #does not delete anything, as expected

user@Host:~$ [ -d $dir_name ] && rm *
user@Host:~$ ls ->  #empty, although there is a test, all files are deleted, why?

我知道双括号[[是 bash 的扩展(或由 ksh 引入),但是为什么在上面的例子中明显的退出状态为 0 时标准测试没有关闭?

答案1

正确的用法是[ -d "$dir_name" ]

通常情况下,不带引号的变量会进行分词:如果$dir_name包含空格,它将扩展为多种的结果命令的 argv[] 数组中的参数;如果是空字符串,则不会产生任何参数。同样的规则也适用于[,它只不过是一个内置命令(实际上也是一个独立的可执行文件)。

因此,您的第二条命令与 不同[ -d "" ]——它实际上扩展为[ -d ]。由于参数数量不同,它变成了一个完全不同的表达式——-d不再表示“目录存在”测试,而是本身用作“字符串参数非空”测试的字符串参数(如[ foo ]),当然会成功。

然而,这些规则不要应用于[[,它会受到 shell 解析器的特殊处理。 内部变量扩展的[[工作方式不同 - 在许多情况下,参数被隐式地“双引号”,因此[[ -d $foo ]][[ -d "$foo" ]]是等效的。 这就是差异的来源。

也可以看看:

相关内容