how to avoid 'unexpected operator' error when comparing 2 strings

this is my file:

#!/bin/sh
a=`cat /home/$USER/Desktop/lol`
c=`cat /home/$USER/Desktop/lol1`
if [ "$a" == "$c" ]; then
echo "$a = $c"
else
echo "They are not equal"
fi

The lol file contains 1aa and the lol1 file contains 1aa as well.
Unfortunately the output is

[: 8: 1aa: unexpected operator
They are not equal

Even when I put -eq instead of == I get

[: 8: Illegal number: 1aa
They are not equal

How can I fix this?
Thank you in advance!

Use = instead of == ... and perhaps prepend each operand with a constant prefix:

 [ X"$a" = X"$c" ]

thank you very much. What is the use of the 'X' you placed there?

The "X" either side of the equals sign allows for either $a or $c to be empty strings.
Afaik the "==" is only valid in bash shell. Use "=" as alister suggests.
The "-eq" operator only applies to numbers not strings.

The test command is what is being invoked to process the expression between the square brackets. If either variable evaluates to nothing (in this case one of your files is empty), then the expression that the test command sees is:

    stuff = 

(nothing trailing the operator if $c was empty) and this is not a legit expression.

Placing an 'x' in front of each variable ensures that the expression does not have any missing components, yet does not change the outcome of the string comparison because both strings will start with the same character.

Shells like Kshell which have a built-in test command (e.g. [[ $a == $b ]]) recognise an empty variable and do the right thing because the expression is being evaluated internally. So, in these scripts you will not encounter the 'x-trick' as it's not needed.

As for your method of cat'ing the files into variables might not be the most efficient way to accomplish your task. I'd use the diff command in this manner:

if diff -q file1 file2 >/dev/null 2>&1
then
    echo "match"
else
    echo "mismatch"
fi

---------- Post updated at 04:35 PM ---------- Previous update was at 04:29 PM ----------

Yes, Bash and Kshell support the == operator, but only within their built-in test function ([[....]]). If a bash/Kshell script uses the single bracket command the contents in the expression are treated differently by the shell and the double equal operator is not valid.

#/usr/env/bin ksh
a=foo
b=bar
if [[ $a == $b ]]     # this is legit
then 
    echo true
else
    echo false
fi 

if [ $a == $b ]       # this will cause an error
then 
   echo true 
else
   echo false
fi

His test expression will never be missing any components even if $a and $c are unset or null, since they are quoted. The test command (whether built-in or not) will see empty strings in their place.

The actual reason for the "x-trick" is that historical implementations are vulnerable to situations where one of the tested values ("$a" and "$c" in this situation) expand into valid test operators. Not knowing what platform the poster is on, I thought it best to be safe.

For more info, see the APPLICATION USAGE section @ test

Regards,
Alister

1 Like

i saw the manual of diff and I find it very interesting. Unfortunately I didn't understand what you did in here:

if diff -q /home/alex/Desktop/lol /home/alex/Desktop/lol1 >/dev/null 2>&1
echo "match"
else
echo "mismatch"
fi

:confused:

If the program returns success, it prints match. If it returns error, it prints mismatch. The rest is redirection to shunt all the unneeded output into /dev/null where it will go away and never be heard from again.

@agama

The "==" is not valid in standard unix "ksh" , and your example gives "Syntax error at line 4 : `==' is not expected.".

I have also checked Bourne Shell and Posix Shell. Still invalid.
However it might be valid in a Conditional Expression in ksh93 ?

The O/P is using "/bin/sh" which could be Bourne Shell or Posix Shell depending on what Operating System version we have here. We can deduce that it is not "bash" or "ksh". Safest to assume Bourne Shell

The rules:

Between single square brackets [...] the expression is evaluated according the the rules for "test" (or the shell emulation of "test").

Between double square brackets [[...]]the expression is evaluated according to the rules for Conditonal Expressions (a separate section of the "ksh" manual).

There is some overlap in the syntax for "test" and a "Conditional Expression" but in standard unix "ksh" none of them include "==".

On the subject of "diff". The "diff -q" syntax is not valid in standard unix. I think you'll find the equivalent "cmp -s" in most of versions.

This is developing into another classic thread where nobody has the same Operating System yet everybody assumes that unix/Linix commands are universal when they are not.

cmp would be more efficient.