operation () {
operator=${exp:1:1} # 2nd character / 1st is ${words:0:1}
# Read into an array as tokens separated by IFS
IFS="$operator"
read -ra array <<< "$exp" # -ra = raw input array
a=array[0]
b=array[1]
# https://www.computerhope.com/unix/bash/read.htm
if [ "$operator" == "+" ]; then
operation=$((a+b))
fi
if [ "$operator" == "-" ]; then
operation=$((a+b)) # => ' 1'
operation=`expr a-b` # => ' 1'
fi
if [ "$operator" == "*" ]; then
operation=$((a*b))
fi
if [ "$operator" == "/" ]; then
operation=$((a/b))
fi
# https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
echo $((operation))
}
exp='2-3'
operation $exp
Everything(almost) works fine, just when making the subtraction operation=$((a+b))
or operation=`expr ab`
I cannot print in anyway minus('-') instad of space(' '), the (-) sign it is been replaced by space. In this example I get ' 1'
instead of '-1'
.
Why is this happening?
I guess you meant to use -
if operator is a minus sign:
if [ "$operator" == "-" ]; then
operation=$((a - b)) # => ' 1'
fi
There are 2 problems with this script. First, arrays elements are not referenced like array[0] is in C but ${name[subscript]}
as it says in man bash:
Any element of an array may be referenced using ${name[subscript]}.
So it should be:
a=${array[0]}
b=${array[1]}
Second, $((var))
should only be used for arithmetic. If you want to print contents of variable just do:
echo "$operation"
All in all, your script should be:
#!/usr/bin/env bash
operation () {
operator=${exp:1:1} # 2nd character / 1st is ${words:0:1}
# Read into an array as tokens separated by IFS
IFS="$operator"
read -ra array <<< "$exp" # -ra = raw input array
a=${array[0]}
b=${array[1]}
# https://www.computerhope.com/unix/bash/read.htm
if [ "$operator" == "+" ]; then
operation=$((a+b))
fi
if [ "$operator" == "-" ]; then
operation=$((a - b))
fi
if [ "$operator" == "*" ]; then
operation=$((a*b))
fi
if [ "$operator" == "/" ]; then
operation=$((a/b))
fi
# https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
echo "$operation"
}
exp='2-3'
operation $exp
Usage:
$ ./script.sh
-1
We're missing some context here:
a=array[0]
is only correct if declare -ia
.exp
?But the problem is a simple matter of lack of quoting:
$ IFS="-"
$ operation="-6"
$ echo $((operation))
6
$ echo "$((operation))"
-6
This is entirely due to the IFS value. bash gets echo -6
and translates that into echo "" 6
with the empty string to the left of the -
delimiter.
Within quotes, word splitting is not performed.
Behaviour documented in 3.5.7 Word Splitting in the manual.
You can set IFS only for the duration of the read command so it does not affect the rest of the script:
$ exp="4-5"
$ IFS=- read -ra array <<<"$exp"
$ declare -p array
declare -a array=([0]="4" [1]="5")
$ printf "%q\n" "$IFS"
$' \t\n'
operation='expr ab' # => ' 1'
operation=$((a+b)) # => ' 1'
you must use - instead +: echo "$((operation))"
This code work properly:
operation () {
operator=${exp:1:1} # 2nd character / 1st is ${words:0:1}
# Read into an array as tokens separated by IFS
IFS="$operator"
read -ra array <<< "$exp" # -ra = raw input array
a=array[0]
b=array[1]
# https://www.computerhope.com/unix/bash/read.htm
if [ "$operator" == "+" ]; then
operation=$((a+b))
fi
if [ "$operator" == "-" ]; then
operation="$((a-b))"
fi
if [ "$operator" == "*" ]; then
operation=$((a*b))
fi
if [ "$operator" == "/" ]; then
operation=$((a/b))
fi
# https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
echo "$((operation))"
}
exp='2-3'
operation $exp
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.