The following table shows that whether a variable is quoted or not, whether you use single or double brackets and whether the variable contains only a space are the things that affect whether using a test with or without -n/-z
is suitable for checking a variable.
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
char : true true true true false false |true true true true false false
If you want to know if a variable is non-zero length, do any of the following:
- quote the variable in single brackets (column 2a)
- use
-n
and quote the variable in single brackets (column 4a)
- use double brackets with or without quoting and with or without
-n
(columns 1b - 4b)
This is the script that produced the table above.
#!/bin/bash
t () { echo -n "true "; }
f () { echo -n "false "; }
unset u
n='' s=' ' z=0 c=c
echo ' 1a 2a 3a 4a 5a 6a |1b 2b 3b 4b 5b 6b'
echo ' [ [" [-n [-n" [-z [-z" |[[ [[" [[-n [[-n" [[-z [[-z"'
for v in unset "null " space "zero " "char "
do
i=${v:0:1}
i=${!i}
echo -en "$v: "
[ $i ] && t || f
[ "$i" ] && t || f
[ -n $i ] && t || f
[ -n "$i" ] && t || f
[ -z $i ] && t || f
[ -z "$i" ] && t || f
echo -n "|"
[[ $i ]] && t || f
[[ "$i" ]] && t || f
[[ -n $i ]] && t || f
[[ -n "$i" ]] && t || f
[[ -z $i ]] && t || f
[[ -z "$i" ]] && t || f
echo
done