Floating point results in Bash integer division

BashBc

Bash Problem Overview


I have a backup script on my server which does cron jobs of backups, and sends me a summary of files backed up, including the size of the new backup file. As part of the script, I'd like to divide the final size of the file by (1024^3) to get the file size in GB, from the file size in bytes.

Since bash does not have floating point calculation, I am trying to use pipes to bc to get the result, however I'm getting stumped on basic examples.

I tried to get the value of Pi to a scale, however,

even though the following works:

~ #bc -l
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
4/3
1.33333333333333333333
22/7
3.14285714285714285714
q
0
quit

A non interactive version does not work:

#echo $(( 22/7 )) | bc
3

This works:

#echo '22/7' | bc -l
3.14285714285714285714

But I need to use variables. So it doesnt help that the following does not work:

#a=22 ; b=7
#echo $(( a/b )) | bc -l
3

I'm obviously missing something in the syntax for using variables in Bash, and could use with some 'pointers' on what I've misunderstood.

As DigitalRoss said, I can use the following:

#echo $a / $b | bc -l
3.14285714285714285714

However I cant use complex expressions like:

#echo $a / (( $b-34 )) | bc -l
-bash: syntax error near unexpected token `('
#echo $a / (( b-34 )) | bc -l
-bash: syntax error near unexpected token `('
#echo $a / (( b-34 )) | bc -l
-bash: syntax error near unexpected token `('

Can someone give me a working correct syntax for getting floating point results with complicated arithmetic expresssions?

Bash Solutions


Solution 1 - Bash

Just double-quote (") the expression:

echo "$a / ( $b - 34 )" | bc -l

Then bash will expand the $ variables and ignore everything else and bc will see an expression with parentheses:

$ a=22
$ b=7
$ echo "$a / ( $b - 34 )" 
22 / ( 7 - 34 )

$ echo "$a / ( $b - 34 )" | bc -l
-.81481481481481481481


Solution 2 - Bash

Please note that your echo $(( 22/7 )) | bc -l actually makes bash calculate 22/7 and then send the result to bc. The integer output is therefore not the result of bc, but simply the input given to bc.

Try echo $(( 22/7 )) without piping it to bc, and you'll see.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoel G MathewView Question on Stackoverflow
Solution 1 - BashAdrian PronkView Answer on Stackoverflow
Solution 2 - Bashuser834425View Answer on Stackoverflow