Why does the following IF condition in ksh always evaluate to true?
From ksh(1)
:
Conditional Expressions.
A conditional expression is used with the [[ compound command to test attributes of files and to compare strings. Field splitting and file name generation are not performed on the words between [[ and ]]. Each expression can be constructed from one or more of the following unary or binary expressions: **string** True, if string is not null. ...
So the following expression is true:
[[ somestring ]]
Now consider your second example:
if [[ $SOME_VARIABLE="TRUE" ]]; then
Assuming $SOME_VARIABLE
is "SOMETHINGNOTTRUE", this expands to:
if [[ SOMETHINGNOTTRUE=TRUE ]]; then
"SOMETHINGNOTTRUE=TRUE" is a non-zero length string. It is therefore true.
If you want to use operators inside of [[
, you must put spaces around them as given in the docs (note the spaces):
string == pattern True, if string matches pattern. Any part of pattern can be quoted to cause it to be matched as a string. With a successful match to a pattern, the .sh.match array variable will contain the match and sub-pattern matches. string = pattern Same as == above, but is obsolete.
Because the one argument form of the test is true if the string is not the empty string. Since the only argument ends in =TRUE
it certainly isn't the empty string, so the test evaluates to true.
Space, the final frontier :-)
Always pay heed to your spaces and keep in mind the word splitting.
Just to pile on, this is explicitly called out in the ksh man page (in the description of the test
command):
Note that some special rules are applied (courtesy of POSIX) if the number of arguments to
test
or[ ... ]
is less than five: if leading!
arguments can be stripped such that only one argument remains then a string length test is performed (again, even if the argument is a unary operator)
(emphasis mine)