Search code examples
bashrelational-operators

Why do the following string comparisons return different results?


What is the difference between the following commands and why do they not produce the same output?:

echo $[ "a" == "a" ]

1
 
echo $(( "a" == "a" ))

1

[ "a" == "a" ]; echo $?;

0

Solution

  • echo $[ "a" == "a" ]
    

    uses the deprecated integer expansion syntax, which has been replaced by $(( ... )).

    echo $(( "a" == "a" ))
    

    uses what is called arithmetic expansion: inside $(( ... )), you can have logical and numerical expressions that get calculated before returning the value.

    [ "a" == "a" ]; echo $?
    

    does a logical test in standard bash fashion: the return code of a program is 0 when that program executes successfully, and non-zero otherwise. [ is actually another name for the program called test, which returns success (i.e., 0) when the expression it tests is true.

    Not in your list, but related:

    (( "a" == "a" )); echo $?
    
    0
    

    this does arithmetic expansion, and returns success (0) if the result is true, rather than producing the value of the expression itself.

    [[ "a" == "a" ]]; echo $?
    
    0
    

    [[ ... ]] is bash syntax for doing conditional tests directly instead of calling the program test.

    Some sample usages

    You would use $(( ... )) to initialize variables or echo output, as you did:

    foo=$(( 1 + 4))
    echo $(( 5 + 7 ))
    

    You would use [ ... ], (( ... )) and [[ ... ]] in conditional statements:

    if [[ $a == bar ]]; then
       echo $a is bar
    fi
    
    i=0
    while (( i < 10 )); do
       echo i=$i
       i=$(( i + 1 ))
    done