编辑:这是一个更完整的版本,显示了 [(又名test)和 [[ 之间的更多差异.
下表显示了变量是否被引用,使用单括号还是双括号以及变量是否仅包含空格是影响使用带或不带-n/-z的测试是否适合检查的因素一个变量。
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
如果您想知道变量的长度是否为非零,请执行以下任一操作:
- 在单括号中引用变量(第 2a 列)
- 使用
-n 并在单括号中引用变量(第 4a 列)
- 使用双括号,带或不带引号,带或不带
-n(1b - 4b 列)
请注意,在第 1a 列中,从标记为“二”的行开始,结果表明 [ 正在评估变量的 内容,就好像它们是条件表达式的一部分一样(结果匹配描述栏中的“T”或“F”暗示的断言)。当使用[[ 时(第 1b 列),变量内容被视为一个字符串并且不被计算。
第 3a 列和第 5a 列中的错误是由于变量值包含空格且变量未加引号引起的。同样,如第 3b 和 5b 列所示,[[ 将变量的内容评估为字符串。
相应地,对于零长度字符串的测试,第 6a、5b 和 6b 列显示了执行此操作的正确方法。另请注意,如果否定显示比使用相反操作更清晰的意图,则可以否定任何这些测试。例如:if ! [[ -n $var ]]。
如果您使用[,确保不会得到意外结果的关键是引用变量。用[[,没关系。
被抑制的错误消息是“预期的一元运算符”或“预期的二元运算符”。
这是生成上表的脚本。
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF