0
votes

I am getting a few of these errors in my bash script. I am new to the language. Any pointers?

#!/bin/bash
echo "Calculating the value V for all given values"
inflation=(0 0.03 0.05)
tax_rate=(0 0.28 0.35)
for I in inflation
do
        for R in tax_rate
        do
                V=(4000*((1+0.07*(1-R))/(1+I))^10)
                echo -n "$V "

        done

done

This is my output:

Calculating the value V for all given values ./investment.sh: line 9: syntax error near unexpected token (' ./investment.sh: line 9: V=(4000*((1+0.07*(1-R))/(1+I))^10)' ./investment.sh: line 12: syntax error near unexpected token done' ./investment.sh: line 12: done'

1
The error comes from the (( inside the assignment. V=(....) defines V as an array of words, as in V=( x y z ), and the for the parser, an unquoted ( inside the list can't be handled. You could write V=('4000*((1+0.07*(1-R))/(1+I))^10'), which would make V a one-element array holding a string representation of this formula, but then I wonder why you need an array, if it has only one element. You could simply use a scalar: V='4000*((1+0.07*(1-R))/(1+I))^10'. - user1934428
If you really want to do floating point arithmetic in a shell, you could convert your script to zsh, which has float variables. - user1934428
Advice to newcomers: If an answer solves your problem, please accept it by clicking the large check mark (✓) next to it and optionally also up-vote it (up-voting requires at least 15 reputation points). If you found other answers helpful, please up-vote them. Accepting and up-voting helps future readers. Please see the relevant help-center article - Gilles Quenot

1 Answers

1
votes
  1. always test your code to https://shellcheck.net on errors (you have too much do statements)
  2. bash can't compute floating numbers itself, use [1] instead
  3. to do arithmetic substitution, use $(( ))
  4. to do arithmetic, without arithmetic substitution, use (( )) form
  5. UPPER CASE variables are reserved for system, better use lower case
  6. inflation=(0 0.03 0.05) is an array, you can access it via "${inflation[@]}"
  7. quote variables ! [2]

[1]

bc <<< "scale=2; (4000*((1+0.07*(1-$r))/(1+$i))^10)"

[2] Learn how to quote properly in shell, it's very important :

"Double quote" every literal that contains spaces/metacharacters and every expansion: "$var", "$(command "$var")", "${array[@]}", "a & b". Use 'single quotes' for code or literal $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. See
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words

Command Substitution: "$(cmd "foo bar")" causes the command 'cmd' to be executed with the argument 'foo bar' and "$(..)" will be replaced by the output. See http://mywiki.wooledge.org/BashFAQ/002 and http://mywiki.wooledge.org/CommandSubstitution

$((...)) is an arithmetic substitution. After doing the arithmetic, the whole thing is replaced by the value of the expression. See http://mywiki.wooledge.org/ArithmeticExpression

((...)) is an arithmetic command, which returns an exit status of 0 if the expression is nonzero, or 1 if the expression is zero. Also used as a synonym for "let", if side effects (assignments) are needed.

Finally

#!/bin/bash
  
echo "Calculating the value v for all given values"
inflation=(0 0.03 0.05)
tax_rate=(0 0.28 0.35)
for i in "${inflation[@]}"; do
    for r in "${tax_rate[@]}"; do
        v="$(bc <<< "scale=2; (4000*((1+0.07*(1-$r))/(1+$i))^10)")"
        echo -n "$v "
    done
done
echo

Output

Calculating the value v for all given values
7840.00 6480.00 5920.00 5360.00 4400.00 4000.00 4400.00 4000.00 3600.00