Kent Pawar
Kent Pawar

Reputation: 2606

Why does the following IF condition in ksh always evaluate to true?

Consider, below code works as expected:

if [[ $SOME_VARIABLE = "TRUE" ]]; then
   echo "Only echoed when \$SOME_VARIABLE stores string \"TRUE\"."
fi

But when I remove the space surrounding the equality operator it always evaluates to 0 exit status (At least that's what I assume it must be returning as it is taken as true):

if [[ $SOME_VARIABLE="TRUE" ]]; then
   echo "Always true."
fi

UPDATE:

Just to confirm whether the issue lies with the equality operator or not:

#!usr/bin/ksh

SOME_VARIABLE=FALSE

if [[ $SOME_VARIABLE == "TRUE" ]]; then
   echo "Only echoed when \$SOME_VARIABLE stores string \"TRUE\"."
fi


if [[ $SOME_VARIABLE=="TRUE" ]]; then
   echo "Always true."
fi


[kent@TEST]$ sh test.sh
Always true.

UPDATE:

Summary:

  1. Using = is the same as == above, but is obsolete.
  2. ALWAYS mind your spaces.

Upvotes: 2

Views: 3240

Answers (3)

glenn jackman
glenn jackman

Reputation: 246877

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)

Upvotes: 0

Jens
Jens

Reputation: 72667

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.

Upvotes: 2

Rob Napier
Rob Napier

Reputation: 299355

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.

Upvotes: 4

Related Questions