4

I am running the following script:

#!/bin/bash
# This script acts as a simple calculator for add, subtract, multiply and divide.
echo "Kindly ENTER 'a' to select for addition"
echo "Kindly ENTER 's' to select for subtraction"
echo "Kindly ENTER 'm' to select for multiplication"
echo "Kindly ENTER 'd' to select for division"
read oper
echo "Please ENTER any number of your choice"
read no1
echo "Please ENTER another number of your choice"
read no2
if [ $oper -eq a ]; then 
echo "Your addition result is: $(($no1 + $no2))" 
elif [ $oper -eq s ]; then 
echo "Your subtraction result is: $(($no1 - $no2))"
elif [ $oper -eq m ]; then 
echo "Your multiplication result is: $(($no1 * $no2))"
elif [ $oper -eq d ]; then 
echo "Your division result is: $(($no1 / $no2))"
else echo "Your selection from the begining was incorrect"
fi

This is the error/output:

./test2.sh: line 12: [: m: integer expression expected
./test2.sh: line 13: [: m: integer expression expected
./test2.sh: line 14: [: m: integer expression expected
./test2.sh: line 15: [: m: integer expression expected
Your selection from the begining was incorrect

What could be the cause please?

  • 2
    -eq is for numeric comparisons; use = for string comparison. Read help test for more details. – steeldriver Jun 8 '18 at 17:09
  • 1
    Too bad @steeldriver elected to disregard the warning written whenever a comment is written: Avoid answering questions in comments. Now you can not accept the correct answer. – pipe Jun 8 '18 at 20:37
5

The -eq operator is a relational operators that are specific to integer values. These operators do not work for string values unless their value is integer.

So use = which checks if the value of two string operands are equal or not

5

As others have stated, -eq is a comparison operator that only applies to integers. The shell test utility has several operands for different purposes. It may be useful to get a better understanding of them all.

File test operators

  • -b - True if file is a block special file
  • -c - True if file is a character special file
  • -d - True if file is a directory
  • -e - True if file exists
  • -f - True if file is a "regular file"
  • -g - True if file has SGID bit set
  • -h - True if file is a symbolic link
  • -L - True if file is a symbolic link
  • -p - True if file is a FIFO
  • -r - True if you have read access to file
  • -S - True if file is a a socket
  • -s - True if file size is greater than 0
  • -u - True if file has setuid flag set
  • -w - True if you have write access to file
  • -x - True if you have execute permissions to file

String operators (Will work with integers but will treat them as strings)

  • = - True if left hand string is equal to right hand string
  • != - True if left hand string is not equal to right hand string
  • -z - True if length of string is zero
  • -n - True if length of string is non-zero
  • string - True if string exists

Relational operators (Will not work with strings)

  • -eq - True if left hand integer is equal to right hand integer
  • -ne - True if left hand integer is not equal to right hand integer
  • -gt - True if left hand integer is greater than right hand integer
  • -ge - True if left hand integer is greater than or equal to right hand integer
  • -lt - True if left hand integer is less than right hand integer
  • -le - True if left hand integer is less than or equal to right hand integer

Boolean operators

  • ! - True if expression is false
  • -o - True if either left hand expression or right hand expression are true
  • -a - True if both left hand expression and right hand expression are true

Arithmetic operators (Within shell arithmetic expansion or expr)

  • + - Adds values on either side of the operator
  • - - Subtracts right hand integer from left hand integer
  • * - Multiplies values on either side of the operator
  • / - Divides left hand integer from right hand integer
  • % - Divides left hand integer from right hand integer and returns remainder
  • = - Assigns right hand to left hand
  • == - True if both integers are equal
  • != - True if both integers are not equal

Other

  • -t - True if file descriptor is open and associated with a terminal
  • I really don't see the point in this extremely verbose answer, it's just annoying having to scroll past this list that's available from the man-page, while not adding anything substantial to this specific question. – pipe Jun 8 '18 at 20:41
  • 1
    @pipe: Virtually every answer ever posted on this site can be found in a man page, should we stop answering all questions because you don't see the point? – Jesse_b Jun 8 '18 at 20:44
  • 2
    No, just quote the relevant parts. – pipe Jun 8 '18 at 21:20
3

For educational purposes, an alternative way to code the calculator. Feel free to ask questions.

#!/bin/bash
declare -A operations=([addition]=+ [subtraction]=- [multiplication]='*' [division]=/)
PS3="Which calculation do you want? "
select ans in "${!operations[@]}" quit; do
    [[ $ans == quit ]] && break
    [[ -z $ans ]] && continue
    read -p "Enter two numbers separated by a space: " -r a b x
    echo "Your $ans result is: $(( a ${operations[$ans]} b ))"
done

  1. PS3 is the bash variable used for the select prompt. It's better then echo because select will re-prompt as often as needed -- for example, if you enter an invalid response.
  2. the '*' is quoted to prevent it from expanding into a list of filenames. See Filename expansion in the bash manual. In hindsight, that may not be required, I can't quickly find a definitive statement in the manual. In general with bash, when uncertain, adding quotes is usually the right way to go.
  • Thank you for sharing this. However, could you add comment lines to explain each line and why the program works the way it does. – Sparks026 Jun 9 '18 at 21:54
  • Do you have any specific questions? As opposed to "explain everything". Start with help declare and help select from a bash prompt – glenn jackman Jun 9 '18 at 23:12
  • - You used PS3 instead of echo? - Why was the * for multiplication highligted? - I will need your Kind explanation for the commands within the select function. Starting from the usage !operations[@]? Thanks – Sparks026 Jun 11 '18 at 11:31
  • Added some comments to my answer – glenn jackman Jun 11 '18 at 13:41
1

As @steeldriver wrote, use = instead of -eq.

  • 1
    Although this is correct, providing details that help explain the answer would be far better. For example, mentioning where a user could find details about command usage at a minimum (man test or help test), yields a much more thorough answer and is more likely to be beneficial to others who come here seeking assistance. – Timothy Martin Jun 8 '18 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.