我最近进行的一项测试对以下bash
命令的输出有疑问:
var=; [ -n $var ]; echo $?; [ -z $var ]; echo $?
结果是0
and 0
,表示两个一元运算符的返回码都没有错误。这意味着$var
解析为null
(空)和“非空”(非空),对吗?
这怎么可能?
我最近进行的一项测试对以下bash
命令的输出有疑问:
var=; [ -n $var ]; echo $?; [ -z $var ]; echo $?
结果是0
and 0
,表示两个一元运算符的返回码都没有错误。这意味着$var
解析为null
(空)和“非空”(非空),对吗?
这怎么可能?
不,这意味着它无法[
修复。在这两种情况下$var
,都没有计算结果,并且命令只是分别执行[ -n ]
和[ -z ]
,这两种结果都为真。如果要测试变量本身的值,则必须引用它以使其正确处理。
$ var=; [ -n "$var" ]; echo $?; [ -z "$var" ]; echo $?
1
0
您需要将 $var 括起来:
$ [ -n "$var" ]; echo $?
1
请记住,右方括号只是语法糖:您不需要它。这意味着您的线路:
$ [ -n $var ]; echo $?
将扩展为(因为 $var 为空):
$ [ -n ]; echo $?
上面问:“字符串']'是非空的吗?” 答案是肯定的。
确实令人惊讶。如果你用 bashism 语法尝试同样的方法[[
,你会得到1
和0
作为结果。我认为这是一个错误。
var=; [[ -n $var ]]; echo $?; [[ -z $var ]]; echo $?
或者,正如 Ignacio 指出的那样,事实上我一直在直觉地做防御性编码和引用:
var=; [[ -n "$var" ]]; echo $?; [[ -z "$var" ]]; echo $?
[
这种行为让我感到惊讶,因为它是内置的:
$ type [
[ is a shell builtin
只是做了一点测试,系统命令的[
行为与内置命令相同。所以可能它的兼容性有问题:
var=; /usr/bin/\[ -n $var ]; echo $?; /usr/bin/\[ -z $var ]; echo $?