4

I'm trying to write a basic script to calculate the radius and area of a circle, where PI=3.14, and the circumference is given. I am very very new to scripting, and I can't seem to figure this out.

#!/bin/bash
PI=3.14
CIRC=5
RAD=echo "((CIRC/2*PI))" | bc-l
printf "Radius: %.2f" $RAD
AREA=echo "((PI*RAD**2))" | bc-l
printf "Area: %.2f" $AREA

The sum of both equations are not being stored in those variables, and I have no idea why. I hope someone can help explain.

zurebe-pieter
  • 3,246
  • 21
  • 38
remedy
  • 125
  • 1
  • 9
  • 2
    Very close. just `rad=$((cir/2*pi))`, etc. recall that `$(( ...))` performs all math evaluations and using the leading `$` indicates to print the output which can be captured in a variable assignment, i.e. `rad=$(( ))`. Good luck. – shellter Jul 18 '16 at 03:46
  • I thought you had to pipe it through bc because of the decimal value, the builtin only does integer calculations. I think? – remedy Jul 18 '16 at 03:52
  • @shellter the `(())` can't evaluate float expressions, you need to delegate a tool like `bc`. ;). Pls check [\[ this \]](http://stackoverflow.com/q/12722095/1620779) & [\[ this \]](https://www.shell-tips.com/2010/06/14/performing-math-calculation-in-bash/). – sjsam Jul 18 '16 at 03:56
  • 1
    hmmm. I'm used to using ksh93. Sorry, @sjsam 's answer looks good anyway. Good luck to all. – shellter Jul 18 '16 at 03:58
  • @shellter : Is ksh an exception to my above comment? – sjsam Jul 18 '16 at 03:59
  • Yes, I just tried `echo $(( 9.7 * 10.1 ))` and `97.97` was returned. – shellter Jul 18 '16 at 04:01
  • @remedy : Does it **have** to be bash? Zsh and (as has been mentioned above) ksh93 allow for floating point arithmetic. I personally find Zsh also more convenient for programming and interactive use than bash; don't know much about ksh93, so I don't want to compare these. – user1934428 Jul 18 '16 at 09:46
  • @user1934428 Yeah, it's for my intro bash scripting class. Ill have a look into Zsh. Thanks! – remedy Jul 18 '16 at 16:08

2 Answers2

5

Below script would do it :

#!/bin/bash
pi=3.14
circ=5
rad=$( echo "scale=2;$circ / (2 * $pi)" | bc )
printf "Radius: %.2f\n" $rad
area=$( echo "scale=2;$pi * $rad * $rad" | bc )
printf "Area: %.2f\n" $area

Notes

  1. See [ command substitution ].
  2. Never use full uppercase variables in your script as they are usually reserved for the system, check [ this ].
  3. scale with bc controls the precision, check [ this ].
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • Awesome, thanks for the info. I see where I went wrong, I'm using uppercase variables because that's how my teacher wants it. XD – remedy Jul 18 '16 at 03:56
  • 2
    @remedy scale set the number of digits after the decimal point. The manpage says it is a standard function supported by bc.Please check this link for details. – sjsam Jul 18 '16 at 03:59
4
  1. Since bc can print strings, there's no need for printf. Nor backticks or $(), or even some of the variables. With bash, the echo can be replaced with <<<:

    #!/bin/bash
    PI=3.14
    CIRC=5
    bc <<< "scale=2; r=$CIRC/(2*$PI)
            print "'"Radius: ", r, "\nArea: ", '"$PI"'*(r^2), "\n"'
    
  2. POSIX shell code version, using a here document:

    #!/bin/sh
    PI=3.14
    CIRC=5
    bc << snip
          scale=2; r=$CIRC/(2*$PI)
          print "Radius: ", r, "\nArea: ", $PI * (r^2), "\n"
    snip
    
  3. Pure bc:

    #!/usr/bin/bc -q
    pi=3.14; circ=5; scale=2; r=circ/(2*pi)
    print "Radius: ", r, "\nArea: ", pi*(r^2), "\n"
    quit
    
agc
  • 7,973
  • 2
  • 29
  • 50
  • With a here document, this could be made portable to any shell. The Bash `<<<` "here string" syntax is convenient, but easily avoided. (And I don't think `bc` particularly wants or requires the newlines to be escaped.) – tripleee Jul 18 '16 at 06:20
  • @tripleee, you're right, `bc` needed no escapes. The *here document* I'd considered earlier, but then figured if I was going to do that, it might as well *all* be done in `bc`. Fixed. – agc Jul 18 '16 at 17:55