Reputation: 456
I wanted to simulate a vending machine where you can buy things only if you throw 2€ inside.
It works as long as i only enter integer values, but if i enter a character or a float it suddenly stops to work. And throws an error that there is an integer expression expected.
read -p "Throw in money" x
echo ""
while [ $x -ne 2 ] ;
do
case $x in
0.5)
read -p "more money" z
x=$(($x + $z))
;;
1)
read -p "more money" z
x=$(($x + $z))
;;
1.5)
read -p "more money" z
x=$(($x + $z))
;;
"R")
echo "return x"
x=0
;;
?)
echo "enter something else!"
x=0
;;
esac
done
Upvotes: 1
Views: 2931
Reputation: 6537
Bash can only do arithmetic with integers, as stated in the manual.
To do floating point arithmetic, you'd need to do something like piping to bc
:
$ x=1.0; z=0.5
$ bc <<< "$x + $z"
1.5
Comparisons work, sort of, you need to read the output to get the truth value:
$ bc <<< "$x < 1.5"
1
Other choices would be to convert the floats to another internal representation, e.g. counting cents instead of full dollars/euros. Or convert the script to something like zsh, awk or Perl, which can deal with floats.
Here's a sketch for cent-based counting:
#!/bin/bash
total=0
getcoin() {
read -p "Insert coin: " x
case $x in
0.1) cents=10 ;;
0.2) cents=20 ;;
0.5) cents=50 ;;
1|1.0) cents=100 ;;
2|2.0) cents=200 ;;
*) echo "Invalid coin!"; return 0;;
esac
(( total = total + cents))
return 0;
}
while getcoin && [[ $total -lt 200 ]] ; do
printf "You have %d cents\n" "$total"
done
printf "You got %d.%02d € in total\n" $((total / 100)) $((total % 100))
Upvotes: 0
Reputation: 531718
-ne
only does integer comparisons, so $x
must expand to something that the shell recognizes as an integer. Just switch to !=
and compare as a string. Further, since bash
cannot add floating point values either, you'll need to use something like bc
to do the addition.
while [ "$x" != 2 ] ;
do
case $x in
0.5)
read -p "more money" z
x=$( bc <<< "$x + $z" )
;;
1)
read -p "more money" z
x=$( bc <<< "$x + $z" )
;;
1.5)
read -p "more money" z
x=$( bc <<< "$x + $z" )
;;
"R")
echo "return x"
x=0
;;
?)
echo "enter something else!"
x=0
;;
esac
done
Upvotes: 2
Reputation: 580
One approach is to use a regular expression, like so:
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
Upvotes: 0