Reputation: 293
I have the following script, pretty self explanatory but I'm getting super strange issues.
Multiply gives me 0
Division multiplies
Any insight would be awesome!
Thanks, Austen
n1=$1
op=$2
n2=$3
case "$op" in
+)
echo $(( $n1 + $n2 ))
;;
-)
echo $(( $n1 - $n2 ))
;;
*) echo $(( $n1 * $n2 ))
;;
/) echo $(( $n1 / $n2 ))
;;
esac
Upvotes: 1
Views: 119
Reputation: 437608
@kojiro's answer explains the problem with the original code well (*
must be quoted to prevent its interpretation as the default case
branch inside the script, and to prevent pathname expansion when passed as an argument).
@kojiro also points out that you can use variable references in place of literal arithmetic operators in arithmetic expansion expressions ($((...))
). Caveat: only works as $op
- with $
prefix! - not just op
(the $
prefix is otherwise optional in arithmetic contexts in bash).
With that in mind, here's a simplified solution that also performs operator checking. (To make it fully robust, the operands would have to be checked, too).
#!/bin/bash
n1=$1 op=$2 n2=$3
# Allow 'x' to be passed as an alias for '*' (multiplication).
[[ "$op" == 'x' ]] && op='*'
# Ensure that the operator is valid.
case $op in
+|-|'*'|/) # note the quoted '*', needed to prevent interpretation as wildcard
;;
*) # proper use of unquoted *: the everything-else branch
echo "Error: Unexpected operator: $op" >&2
exit 1
esac
# Perform the calculation. Note how the operator is provided via variable $op.
# Note how the reference to variable `op` _must_ be `$`-prefixed in this case,
# unlike the other two references.
echo $(( n1 $op n2 ))
Upvotes: 1
Reputation: 293
Fixed it, but this is how I had to fix it:
#!/bin/bash
n1=$1
op=$2
n2=$3
if [ "$op" == 'x' ]
then
echo $(( $n1 * $n2 ))
else
echo $(( $n1 $op $n2 ))
fi
Upvotes: 0
Reputation: 77107
@gniourf_gniourf's comment is 90% of the answer and fully explains why "division multiplies". The other 10% is that you need to quote the *
argument when you pass it to this code, or else it will glob expand and your third argument will be some filename, which, inside the arithmetic expression, will probably evaluate to 0
. That explains why "Multiply gives me 0".
You could also solve this by setting the noglob
shell option to prevent globs from expanding.
Compare:
echo *
set -f
echo *
Upvotes: 3
Reputation: 7959
Consider using bc
as bash does not handle floats:
echo $((4/3))
1
Using bc
:
echo "4/3" | bc -l
1.33333333333333333333
Upvotes: 1