7

I have a question

a=1
b=2

I want the comparison output to a variable. ie in windows languages you can write something like this. it should print false

print ($a == $b)

tries these below in console.

echo $a -eq $b
echo (( $a -eq $b ))
echo "$a" -eq "$b"
c= $(expr  "$a" -eq "$b"  )
echo $c
Inian
  • 80,270
  • 14
  • 142
  • 161
sjd
  • 1,329
  • 4
  • 28
  • 48

4 Answers4

5

You can use arithmetic expansion.

echo $(( a == b ))

This will print 1 if the expression is true and 0 if the expression is false. No need to add $ before variable names, you can use operators like in C language and the spaces can be omitted. See Bash reference manual:Shell arithmetic for more info.

Having it to print a string "true" or "false" is a bit more tricky. Usually I go with the same as @Inian, but using if ... then .. else ... fi because I usually code under set -euo pipefail:

if (( a == b )); then echo true; else echo false; fi

but we can be smart and do an array:

to_bool[0]="false"
to_bool[1]="true"
echo ${to_bool[ a == b ]}

but I see no difference then printing just 0 or 1.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

Note that bash does not natively support a bool type operator. All the commands/built-ins return an exit code to the shell depending upon its success/failure status. A code 0 to the shell means the operation is success and any non-zero would represent a failure.

So in bash, you do the comparison and need to set the bool strings explicitly, something like

[[ $a == $b ]] && echo true || echo false

Note that using echo true should not confused with the built-ins /bin/true and /bin/false which explicitly set the exit code to the shell to 0 and 1 respectively. The echo statement just prints out the string mentioned to the standard output.

Also note that [[ is a shell keyword extension to the POSIX-ly available [ construct. The former is a added to the bourne again shell and may not available in other POSIX compliant shells. If you are looking for a portable way of doing this, use the [ with the case construct as

[ "$a" -eq "$b" ]
case $? in
    0) printf '%s\n' "true" ;;
    *) printf '%s\n' "false" ;;
esac
Inian
  • 80,270
  • 14
  • 142
  • 161
  • I don't see a case for `case` when you are examining the result code of a command. The `if` statement does this naturally and idiomatically. Perhaps see also [Why is testing “$?” to see if a command succeeded or not, an anti-pattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – tripleee Mar 25 '23 at 10:18
1

I do not think it is possible to do it in bash directly.

But you can do something as the following based on the return code of the comparison operator:

res=0; [ "$s1" == "$s2" ] && res=1
echo $res

It sets res to zero first and then only if the comparison succedes sets the res variable to 1.

Alternatively, something more concise is the following:

[ $s1 -eq $s2 ]; echo $((!$?))

which literally prints the return code of the previously executed command. Note the ! not operator applied to the return code as 0 usually means success i.e. in this case the variable are the same.

Davide Spataro
  • 7,319
  • 1
  • 24
  • 36
-1

If you need it to be POSIX-compliant:

test $a -ne $b && printf 'false'; return 1
unrealapex
  • 578
  • 9
  • 23
  • This will `return 1` regardless of the comparison. You can fix it with a pair of braces. – tripleee Mar 25 '23 at 10:15
  • 2
    Arithmetic expansion is in POSIX, though if you need compatibility back to pre-POSIX shells, `[` is probably the most natural operator. – tripleee Mar 25 '23 at 10:23
  • When following the comments suggestions, probably better no do this as a one-liner. You could do a `if-else` instead. – Jardel Lucca Mar 31 '23 at 04:08