260

I am using SH shell and I am trying to compare a string with a variable's value but the if condition is always execute to true. Why?

Here is some code:

Sourcesystem="ABC"

if [ "$Sourcesystem" -eq 'XYZ' ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Even this is not working:

Sourcesystem="ABC"

if [ 'XYZ' -eq "$Sourcesystem" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Secondly, can we match this with a NULL or empty string?

jww
  • 97,681
  • 90
  • 411
  • 885
James Bond
  • 2,825
  • 2
  • 15
  • 11
  • First in Bourne shell you don't need the extra ';' When I test run the script in Bourne shell, the if condition is false. It will first give an warning: [: ABC: integer expression expected. The output is: "Sourcesystem is NOT Matched ABC". As commented by others, -eq is used for integer comparisons. Use a single equal sign for string comparison in Bourne shell (#!/bin/sh). Your shell should have corrected you in the first place. – Kemin Zhou Mar 21 '16 at 03:52
  • 8
    Voting to reopen. The cited dups are for bash shell, not the anemic sh shell which is sometimes a Posix shell or Dash. – jww Jan 18 '19 at 10:55
  • 1
    Agreed and so voted. `sh` and `bash` bear the same relationship as `C` and `C++`. Even though code written for the first is valid in the second, answers for the second can't be trusted to work in the first. – btilly Apr 17 '20 at 17:27

7 Answers7

364

You should use the = operator for string comparison:

Sourcesystem="ABC"

if [ "$Sourcesystem" = "XYZ" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

man test says that you use -z to match for empty strings.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Mithrandir
  • 24,869
  • 6
  • 50
  • 66
  • 4
    It is not necessary to quote `ABC` or `XYZ`. – ceving Feb 12 '16 at 15:09
  • 49
    If your variable might have spaces in it then quoting is necessary. – William Everett Jan 11 '17 at 19:07
  • 1
    Adjusted the example to make that part clearer @WilliamEverett. – Per Lundberg Jul 28 '17 at 08:54
  • 1
    This method doesn't work with sh nor bash (macOS 11.2) if both strings contain multiple lines, where the first line is equal but further lines are different - then I get always true for a `=` test. With macOS' new zsh, however, I can even leave the quotes out, as in `[ $a = $b ]`, and get the correct result for multi-line strings. – Thomas Tempelmann Feb 10 '21 at 15:33
  • 1
    @Thomas - the OP question is specifically about `sh` not bash or zsh. OP examples would also never me multi-line strings. Multi-line strings should probably take a different approach rather than rely on a feature of zsh, unless you are working in an exclusively zsh environment. Targeting `sh` usually means you need high portability because bash and/or zsh isn't available in all of your environments. I'm on macOS and could target zsh, but then when my scripts are moved to linux system over which I have no control they will fail due to zsh not being present. – Stephen P Feb 24 '21 at 00:14
95

-eq is used to compare integers. Use = instead.

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
53

eq is used to compare integers use equal '=' instead , example:

if [ 'AAA' = 'ABC' ];
then 
    echo "the same" 
else 
    echo "not the same"
fi

good luck

Qign20
  • 531
  • 4
  • 2
32

I had this same problem, do this

if [ 'xyz' = 'abc' ]; then
  echo "match"
fi

Notice the whitespace. It is important that you use a whitespace in this case after and before the = sign.

Check out "Other Comparison Operators".

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
Eswar Yaganti
  • 2,536
  • 1
  • 20
  • 22
12

-eq is the shell comparison operator for comparing integers. For comparing strings you need to use =.

codaddict
  • 445,704
  • 82
  • 492
  • 529
3

-eq is a mathematical comparison operator. I've never used it for string comparison, relying on == and != for compares.

if [ 'XYZ' == 'ABC' ]; then   # Double equal to will work in Linux but not on HPUX boxes it should be if [ 'XYZ' = 'ABC' ] which will work on both
  echo "Match"
else
  echo "No Match"
fi
Shaik Md
  • 597
  • 4
  • 8
  • 22
Jason
  • 11,263
  • 21
  • 87
  • 181
  • 26
    Note that the operator `==` does not work on every shell. `=` is the correct operator to use in order to compare strings, and `==` is sometimes a synonym. – Omer Dagan Mar 08 '15 at 12:26
  • This answer is **wrong** for /bin/sh scripts and will fail. On macOS, the "test" command (also available as "[") treats "="" as "=". On Linux it doesn't. – neuhaus Oct 21 '21 at 08:55
3

Of the 4 shells that I've tested, ABC -eq XYZ evaluates to true in the test builtin for zsh and ksh. The expression evaluates to false under /usr/bin/test and the builtins for dash and bash. In ksh and zsh, the strings are converted to numerical values and are equal since they are both 0. IMO, the behavior of the builtins for ksh and zsh is incorrect, but the spec for test is ambiguous on this.

William Pursell
  • 204,365
  • 48
  • 270
  • 300