2

I am using the bc command in UNIX to parse some math expressions. I have two small functions:

function bashcalc {
      echo $@ | bc -l
}

function2 {
      ...
      catMinusMouse=$(bashcalc "$cat_angle - $mouse_angle")
      cos=$(cosine $catMinusMouse)
      val=$(bashcalc "$cat_radius * $cos")   ##PARSE ERROR
      ...
}

When I tried to run the expression following val, I got quite a few "(standard_in) 1: parse error"s.

My first thought was that the asterisk was the issue so I tried escaping it. That however gave me an illegal character error.

The solution ended up being removing all of the whitespace

   val=$(bashcalc "$cat_radius*$cos")

QUESTION: Why did calculating catMinusMouse (with spaces around the subtraction operator) work while the same format with multiplication did not work?

bobbyjoe93
  • 178
  • 2
  • 7
  • Try running `echo 2 * 3` in a non-empty directory and see if you can figure it out. – Mat May 01 '13 at 09:54
  • That's interesting. However, could I make this work with the use of escaping? If I do `$(bashcalc $cat_radius \* $cos)`, wouldn't I be effectively calling `echo 2 \* 2`, which properly escapes the * and doesn't list the directory? – bobbyjoe93 May 01 '13 at 10:21
  • 1
    Problem isn't at the call site, it's in the expansion of `$@` in the function. jm666's answer covers it. – Mat May 01 '13 at 10:25

3 Answers3

3

you need escape the * or enclose it into "quotes"

3 variants:

#!/bin/bash

function bashcalc {
    echo "$@" | bc -l
}

function2() {
    cat_radius=0.9
    catMinusMouse=0.4

    val=$(bashcalc "$cat_radius" "*" "c($catMinusMouse)")
    echo $val

    #or
    val=$(bashcalc "$cat_radius * c($catMinusMouse)")
    echo $val

    #or
    val=$(bc -l <<EOF
$cat_radius * c($catMinusMouse)
EOF
)
    echo $val
}

function2
clt60
  • 62,119
  • 17
  • 107
  • 194
  • 1
    You should properly double-quote all variable expansions here, but the beef is the use of `"$@"` pro bare `$@`. – tripleee May 01 '13 at 10:44
2

The real problem here is that you have not quoted $@ in your bashcalc function.

Change it to:

function bashcalc {
      echo "$@" | bc -l
}

Even better, don't use echo. Change it to:

bashcalc() {
    bc -l <<< "$@"
}
dogbane
  • 266,786
  • 75
  • 396
  • 414
1

Try with the following:

val=$(echo "$cat_radius * $cos"| bc)

that is, pipe to bc (bashcalc) and it will make the calculation.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 2
    That's new. The program `bc` predates Bash by a large margin, so whatever the name stands for, it's certainly not "Bash Calculator". [Wikipedia](http://en.wikipedia.org/wiki/Bc_programming_language) says it's "basic calculator". – tripleee May 01 '13 at 10:42