Fast Bash Math
7
A lot of time shell scripts need to do some sort of math. Bash's innability to do floating point arithmatic has lead to some pretty neat workarounds, often times these workarounds are slow. If you need a lot of calculations done with speed, you'll find this snippet useful
#!/bin/bash
sum=$(( 4 + 4 ))
echo $sum
difference=$(( 4 - 4 ))
echo $difference
product=$(( 4 * 4 ))
echo $product
quotient=$(( 4 / 4 ))
echo $quotient
remainder=$(( 4 % 4 ))
echo $remainder
sum=$(echo "scale=3; 4 + 4" | bc)
#This can also do more complicated math.
sum=$(echo "scale=3; "2 * ( 4 + 4 ) / 4" | bc)
22.22 48.583
24.1 24.594
29.389 283.298
294.293 29.1
...
92.2 19.494
#!/bin/bash
##
# Make some fifos we can connect to.
##
mkfifo /tmp/bc.in
mkfifo /tmp/bc.out
##
# Attach file descriptors to those fifos.
##
exec 7<>/tmp/bc.in
exec 8<>/tmp/bc.out
##
# Start a single bc process in background and connect our fds to
# it's stdin, stdout, stderr we can use to do all of our math. We can
# do this because bc is an interpreter, with it's own shell. Using
# these same methods we can do inline perl/php/python, etc in
# bash.
##
bc 0<&7 1>&8 2>&8 &
while read numerator denominator
do
echo "scale=5; $numerator / $denominator" >&7
read quotient <&8
# bc errors have ':' in them somewhere.
if [ "$quotient" != "${quotient//:/}" ; then
echo "Error: $quotient"
else
echo "Answer of $numerator / $denominator is $quotient."
fi
done
##
# Shutdown our bc process
##
echo "quit" >&7
##
# Close down our file descriptors.
##
exec 7>&-
exec 7<&-
exec 8>&-
exec 8<&-






This line does not execute and should read:
sum=$(echo "scale=3; 2 * ( 4 + 4 ) / 4" | bc)
Should the fifos be removed on exit?