1

I am trying to write a script I will call calc.sh that does basic calculations using the arguments for the script ( $1, $2 and $3). For instance I'd like to get 2 as result for ./calc.sh 10 / 5

My start goes as this:

if [ $2 -eq "+" ] ; then res=`expr $1 + $3` ; echo "$res" ; fi

But it won't work, I get something like : Line 2 : [ +: an integer expression was expected

NOw That I used == to make the comparison is working fine for all the operations except the division /. The code now is:

if [ $2 == "+" ] ; then res=`expr $1 + $3` ;
elif [ $2 == "-" ] ; then res=`expr $1 - $3` ;
elif [ $2 == "x" ] ; then res=`expr $1 \* $3` ;
elif [ $2 == "/" ] ; then res=`expr $1 \/ $3` ;
else res=`Operación no válida` ;
fi ; echo "$res"

But if I try ./calc.sh 10 / 5 , I will get: "line 4: 10 / 5 : syntax error: invalid arithmetic operator (the error element is "\ 5 ")... Alas as I am typing I'm realising it should be $1 / $3 ...
:)

Thomas
  • 6,362

4 Answers4

1

If you are using a bashshell, you can try:

if [ $2 == "+" ] ;then
 res=$(($1 + $3))
 echo $res 
fi

Edit

Change the next line (note the substitution of ' by "):

else res=`Operación no válida` ;

To:

else res="Operación no válida" ;

Edit 2

Instead of using so many if else statements, you can use a case statement:

case $2 in
+)
  res=`expr $1 + $3`
  ;;
-)
  res=`expr $1 - $3`
  ;;
/)
  res=`expr $1 \/ $3`
  ;;
x)
  res=`expr $1 \* $3`
  ;;
*)
  res="Operación inválida"
  ;;
esac

echo "$res"
  • 1
    Thank yo, I tried with == and is working fine except for the division symbol. if [ $2 == "+" ] ; then res=expr $1 + $3 ; elif [ $2 == "-" ] ; then res=expr $1 - $3 ; elif [ $2 == "x" ] ; then res=expr $1 \* $3 ; elif [ $2 == "/" ] ; then res=expr $1 \\ $3 ; else res=Operación no válida ; fi ; echo "$res" – Lorena R Nov 14 '16 at 12:26
  • Division is /, so replace res=expr $1 \\ $3 with res=$(expr $1 / $3) – Iñaki Murillo Nov 14 '16 at 12:38
  • 1
    The final code I used worked pretty well (see in the edited question), except for the case when I don't use one of the described operators (for instance something like./calc.sh 3 r 4) I won't get the error message from the else echo "operación inválida". But the question was pretty much answered. Should I do something now to signal this? – Lorena R Nov 15 '16 at 13:49
  • @LorenaR I updated my answer to address the problem with else echo "operación inválida". Also, you can select the correct answer by clicking the "tick" below the two arrows – Iñaki Murillo Nov 15 '16 at 14:04
1

The script:

#!/bin/sh
IFS=" " # join arguments with a space character
echo "$* = $(( $* ))"

With + it is easy:

./calc.sh 10 + 2
10 + 2 = 12

But asterisk has to be escaped

./calc.sh 10 \* 2
10 * 2 = 20

or

./calc.sh 10 "*" 2
10 * 2 = 20
hschou
  • 2,910
  • 13
  • 15
0

As @AlexP has already pointed out, you are doing arithmetic instead of a string comparison.

I would also strongly suggest that you use double brackets [[]] instead of single ones.

Your code can then be written as:

#!/bin/bash

if [[ $2 == "+" ]]; then
    echo $(($1+$3))
elif [[ $2 == "/" ]]; then
    echo $(($1/$3))
fi

Execution examples:

./math.sh 2 + 7
9
./math.sh 7 / 2
3
  • note than you can use = instead of == as those are synonyms when using double brackets – Ikaros Nov 14 '16 at 12:36
  • Yeah, but I really prefer not to. In every other language, = is an assignment operator, and I like to keep it that way! –  Nov 14 '16 at 12:37
  • = vs == is one of the methods some languages have used to distinguish between assignment and equality. There are several others like := vs = (almost as common), <- vs =... See also https://en.wikipedia.org/wiki/Assignment_%28computer_science%29#Assignment_versus_equality. In any case the [ command and the [[..]] construct have no assignment operator. – Stéphane Chazelas Nov 15 '16 at 14:32
  • Ok, I stand corrected. Every other language I have ever used use = as an assignment operator. –  Nov 15 '16 at 17:08
0

None of +, -, x or / are special to the shell or the [ command. Your problem here is that:

  • -eq is for numeric comparison. Use = instead of string comparison
  • you forgot to quote your variables
  • == is not a standard sh [ operator

So:

if [ "$2" = + ]; then
  res=`expr "$1" + "$2"`
fi

Or use a case construct:

case $2 in
  + | - | /) res=`expr "$1" "$2" "$3"`;;
          x) res=`expr "$1" "*" "$3"`;;
          *) echo >&2 invalid; exit 1;;
esac

Note that you'd only use expr if you had to deal with ancient systems. Modern standard sh implementations have arithmetic expansions built-in via the $((...)) operator and a better form of command substitution with $(...) instead of `...`.

  • Thank you for the info. I didn't know about the expr. From now on I will use the $((...)) operator. – Lorena R Nov 15 '16 at 13:54