[SOLVED] How to put the division of two variables in another variable?
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Use bc (binary calculator) for any math you want to do.
For integer/non-floating point:
var3=$(echo $var1 \/ $var2 |bc)
So if var1 is 6 and var2 is 2 then var3 will result in value of 3.
NOTE: Bash has integer math built into it but if you get in the habit of using bc you can expand what you do as shown below.
For floating point you'd have to use "bc -l".
var3=$(echo $var1 \/ $var2 |bc -l)
So if var1 is 7 and var2 is 2 then var3 will result in value of 3.500000.
You might also need to echo "scale=<value>" into bc -l if you want to limit how many digits so you'd have to put a new line between that and the division.
var3=$(echo -e scale=2 "\n" $var1 \/ $var2 |bc -l)
So if var1 is 7 and var2 is 2 then var3 will result in value of 3.50
You can do "man bc" for more detail on the bc command.
Use bc (binary calculator) for any math you want to do.
For integer/non-floating point:
var3=$(echo $var1 \/ $var2 |bc)
So if var1 is 6 and var2 is 2 then var3 will result in value of 3.
NOTE: Bash has integer math built into it but if you get in the habit of using bc you can expand what you do as shown below.
For floating point you'd have to use "bc -l".
var3=$(echo $var1 \/ $var2 |bc -l)
So if var1 is 7 and var2 is 2 then var3 will result in value of 3.500000.
You might also need to echo "scale=<value>" into bc -l if you want to limit how many digits so you'd have to put a new line between that and the division.
var3=$(echo -e scale=2 "\n" $var1 \/ $var2 |bc -l)
So if var1 is 7 and var2 is 2 then var3 will result in value of 3.50
You can do "man bc" for more detail on the bc command.
The \ in front of the / prevents the shell from giving the / special meaning. It's just saying treat the next character as a literal, rather than a special character.
What MensaWater is doing with that statement is formatting a string and sending it to bc as a command. I believe you could just enclose the input to bc in quotes, which might be more legible, as follows ...
echo "$var1/$var2" | bc
... as long as you don't use single quotes, the shell will convert the $vars to their values in the string.
The \ in front of the / prevents the shell from giving the / special meaning. It's just saying treat the next character as a literal, rather than a special character.
What MensaWater is doing with that statement is formatting a string and sending it to bc as a command. I believe you could just enclose the input to bc in quotes, which might be more legible, as follows ...
echo "$var1/$var2" | bc
... as long as you don't use single quotes, the shell will convert the $vars to their values in the string.
Wait isn't the shell supposed to take the special meaning of / (i.e. division)? Also isn't $ a special character like /? Why doesn't it have a \ in front of it too?
If you escaped the $ sign, the shell would pass "$var", when you want the value of $var. You only want to escape things that you don't want the shell to process.
Yes, the "/" could be used for integer division, but that wasn't what you asked. You asked why it was escaped. It is escaped, so it gets passed literally to bc, which is another program that does math.
You can also do math in the shell with something like var3=$(( var1 / var2 ));
The reason I use escapes and the parentheses is that over time I've found that various scripts work better with them. Having them when they're NOT necessary seldom hurts anything but NOT having them when they are necessary gives very odd results indeed.
MensaWater, you'll get no argument from me. I was just trying to clear up some confusion. Shell scripts can be very hard to read; especially when you're just getting started. I still cringe at the math syntax.
"Bash" is one of the languages/interpreters that can execute a script. While you can use a text editor to write in any language, the syntax will eventually differ from language/interpreter to another, that's what he was asking.
Some scripting languages are similar enough to be compatible to some degree (like bash and dash), but even then there will be some differences. Other languages are more dramatically different, like python, which forces you to "format" the text with indentation (you can do that in bash, but it's entirely optional), as far as I know.
Wait isn't the shell supposed to take the special meaning of / (i.e. division)? Also isn't $ a special character like /? Why doesn't it have a \ in front of it too?
As long as there are no critical file operations involved, it's safe to just test stuff like that on the command line or mini-scripts focusing just on one aspect like this.
What happens in this instance is that the second command, bc (which does math, more sophisticatedly than bash's built-in math), after the "pipe", "|", is the one that is supposed to interpret "/" as a division symbol; "echo" is just "telling" the math bc should do, not solving anything itself.
In this expression escaping the division slash is strictly unnecessary/has no effect, since the slash/division isn't within a context that would be interpreted as a division anyway. That is, if you issue on the command prompt, "echo 12/2" (or "var1=12 ; var2=2 ; echo $var1/$var2"), the output will be literally "12/2", not "6". And bc, unlike bash, "gets" that "\/" really means just "/".
In the other hand, if you issued "echo $((12/2))" (or that with vars), the output is "6". But "echo $((12\/6))" will complain of an invalid operator, "\/".
You "could" do "echo $((12/2)) | bc", but that has the same effect of "echo 6 | bc", that is, bc is doing nothing, is like telling someone to type "12/2" in a calculator and that person typing already just 6.
I hope I didn't make things even more confusing while trying to make it a little bit clearer.
I personally prefer to use quotes to pass literal expressions (and to not escape anything that's not needed, by consequence) -- which sometimes I'll only find out when whatever I'm trying to do isn't working, anyway. I'm not saying that it's the "proper way", I just find it easier, less ambiguous, to read.
Altough this is solved, I'll write my solution in a nutshell:
If it is an integer operation with an integer result, the bash built-in feature is enough:
$var3=$(($var2/$var1)) or $var3=$[$var2/$var1]
in this case if you try a division with a non-integer result, $var3 gets the 0 value always,
because bash always answer with integers, so the solution is to use bg, as pointed...
$var3=$(echo -e $var1/$var2 "\n" scale=2 | bc -l)
Note the -e switch, that tells echo to send the \n literally to bc, this is because bc need
a \n between operations, so if we divide 3/5, bc gets something like this:
scale=2
3/5
and exits, levaing the result at var3.
Ellegant.
Last edited by jordialcoi; 06-06-2014 at 05:11 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.