Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

#!/bin/bash
S1='foo'
S2='bar'
if [ $S1=$S2 ];
then
    echo "S1('$S1') is equal to S2('$S2')
fi
echo $S1
echo $S2

The output is:

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

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

share|improve this question

2 Answers 2

up vote 10 down vote accepted

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
                 null.
          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.

share|improve this answer
    
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.

share|improve this answer
    
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 Feb 18 '11 at 21:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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