No, it's not the same. There is a difference between what you see, and what expr
sees, i.e. the string that it will try to evaluate. This is because every word of the command invocation (just like with every command invocation in Tcl) is subjected to substitution before the command is executed.
First case: the braces prevent the contents of the expression from being prematurely substituted. You see {$a eq $b}
, expr
sees $a eq $b
. This is two operands ($a
and $b
) and an operator (eq
): expr
can work with this.
Second case: the three arguments are substituted before they are passed to expr
. You see $a eq $b
, expr
sees abc eq abcd
. That's two nonsense values and an operator, and expr
can't deal with that.
If there is a string that isn't a boolean value or the name of an operator in an expr
expression, it should be part of a variable substitution ($abc
), or the name of a function (abc(...)
), or part of a command substitution ([... abc ...]
), or else be explicitly quoted ("abc"
or {abc}
).
Always brace the arguments to expr
. Doing so prevents many problems, this one being one of the milder.
Documentation: expr