The following script does not behave as I would have expected. Adding spaces around the '=' in the conditional made it perform how I wanted, but it got me thinking, what is it actually doing inside the conditional?

if [ $S1=$S2 ];
    echo "S1('$S1') is equal to S2('$S2')
echo $S1
echo $S2

The output is:

S1('foo') is equal to S2('bar')

The contents of S1 and S2 don't change from what they are assigned, so the = doesn't perform an assignment.


It's helpful to remember that [ is actually a command, usually also available as test. In bash, it's a builtin, so you can see the documentation with man builtin.

In that documentaiton:

          test and [ evaluate conditional expressions using a set of rules
          based on the number of arguments.

          0 arguments
                 The expression is false.
          1 argument
                 The expression is true if and only if the argument is not
          2 arguments
          3 arguments

The two-argument rules are various tests, and the three-argument ones are generally comparisons. When you put a space around the =, you get three arguments. But when you put it all together, you get one argument, and as you can see, if that argument isn't null, it returns true.

  • Very good explanation on why the spaces around the equals sign make a difference! – Cory Klein Feb 18 '11 at 21:15

The equals operator does nothing in this case.

The expression $S1=$S2 evaluates to an actual string, with the values of S1 and S2 in place, effectively the string literal "foo=bar".

Since this string literal is not null, the statement

if [ "foo=bar" ];

evaluates to true, and the body of the if statement is executed.

  • I figured this one out right before submitting the question, but as the atmosphere of stackexchange is one of learning, I thought I may as well add my question and answer to the pool of knowledge that is stackexchange, rather than just discarding it. – Cory Klein Feb 18 '11 at 20:43
  • 3
    And what you're looking for is in fact [ "$S1" = "$S2" ]. Otherwise, if $S1 or $S2 contain wildcard or spaces, they would be expanded (e.g. try both with S1='a = a -o a' and S2='b'). In ksh, bash and zsh, you can use [[ $S1 = $S2 ]], because [[]] is special shell syntax whereas [ is an ordinary command with a funny name. Note that you also need spaces around the brackets in either case. – Gilles 'SO- stop being evil' Feb 18 '11 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.