2
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 a-b` 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?

2
  • 1
    expr a-b is not the same as expr "$a" - "b". Why didn't you use $((a - b)) for subtraction? Commented Dec 20, 2020 at 23:38
  • I am newbe, thank you for your useful comment =). I have been having problems understanding differences among that kind of expressions. But I am improving,. Commented Dec 23, 2020 at 16:52

4 Answers 4

0

use space around - :

exp=' 2 - 3 ' 

or

operation = expr a - b

or

COUNT="expr $FIRSTV - $SECONDV"

also see this [link]1

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for your answer. But i am still not getting to work this script, even after trying this options. =(
I send another answer.
0

We're missing some context here:

  • This a=array[0] is only correct if declare -i a.
  • What is 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' 

2 Comments

I need a little more time to research on your answer, as I am having problems understanding it. I thank you very much for it, and will write in a couple of days (after research) with some comment.
Add this page to your research list: unix.stackexchange.com/q/171346/4667 -- it focuses on the security implications of quoting, but the intro links to several other questions that are about quoting.
0

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 

4 Comments

I really apologize, I copy/pasted your code and didn't work, maybe there is another situation with my bash installation or something, but thank you very much. =)
@DiegoMota: what do you mean by didn't work?
@DiegoMota: it works well for me with Bash 5.0.18 and Bash 5.0.3. Make sure you copied it correctly. How do you run it?
I will check my bash version, I have a file named arithmeticOperations.sh with exactly the same code that I posted. This problem is related to this link (hackerrank.com/challenges/…) and I am trying to solve it according to it. As I told you, I will check my bash version. I run it using 'bash arithmeticOperations.sh'.
0
  1. I remove this line operation='expr a-b' # => ' 1'
  2. In this line operation=$((a+b)) # => ' 1' you must use - instead + :
  3. For output use "" around the variables:

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 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.