[[ is keyword, [ is a shell builtin
This is from the 'Advanced Bash Scripting Guide':
The [[ ]] construct is the more versatile Bash version of [ ]. This is the extended test command, adopted from ksh88.
* * *
No filename expansion or word splitting takes place between [[ and ]], but there is parameter expansion and command substitution. file=/etc/passwd
if [[ -e $file ]]
then
echo "Password file exists."
fi
Using the [[ ... ]] test construct, rather than [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, <, and > operators work within a [[ ]] test, despite giving an error within a [ ] construct.
Arithmetic evaluation of octal / hexadecimal constants takes place automatically within a [[ ... ]] construct. # [[ Octal and hexadecimal evaluation ]]
# Thank you, Moritz Gronbach, for pointing this out.
decimal=15
octal=017 # = 15 (decimal)
hex=0x0f # = 15 (decimal)
if [ "$decimal" -eq "$octal" ]
then
echo "$decimal equals $octal"
else
echo "$decimal is not equal to $octal" # 15 is not equal to 017
fi # Doesn't evaluate within [ single brackets ]!
if [[ "$decimal" -eq "$octal" ]]
then
echo "$decimal equals $octal" # 15 equals 017
else
echo "$decimal is not equal to $octal"
fi # Evaluates within [[ double brackets ]]!
if [[ "$decimal" -eq "$hex" ]]
then
echo "$decimal equals $hex" # 15 equals 0x0f
else
echo "$decimal is not equal to $hex"
fi # [[ $hexadecimal ]] also evaluates!
Following an if, neither the test command nor the test brackets ( [ ] or [[ ]] ) are strictly necessary. dir=/home/bozo
if cd "$dir" 2>/dev/null; then # "2>/dev/null" hides error message.
echo "Now in $dir."
else
echo "Can't change to $dir."
fi
The "if COMMAND" construct returns the exit status of COMMAND.
Similarly, a condition within test brackets may stand alone without an if, when used in combination with a list construct. var1=20
var2=22
[ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2"
home=/home/bozo
[ -d "$home" ] || echo "$home directory does not exist."
word splitting and file name generation are not done inside the extended test facility, and therefore there is less need to quote.
You did not quote ${CHECK} in your first example and I think that is the difference. I don't know exactly what happens in the shell, but I think that the shell basically tried to use the '-n' test w/o an operand, possibly, because w/o quotes it treated the contents of ${CHECK} as a file name and could not find it (since it was null) which might be why the "not found" came up.
I quoted it using the test facility [ ] (not extended) which prevented file name expansion and allowed the result of ${CHECK} to be tested against the '-n' operator, and it worked fine, but w/o quotes I reproduced your errror.
I'm more familiar with ksh and HP-UX's "posix shell" (based on ksh) and the [[ ]] facility use is encouraged over [ ].
Quoting the "${CHECK1}" construct would create a zero length string if the variable was null, yes, that is correct. So [ ] would work for that.
I use ksh with [[ ]] -- simply to avoid problems like this. And any time I work with string variables I try to enclose them in double quotes so they are "seen" correctly by the shell.