-   Programming (
-   -   Bash Script, calculate output. (

eldaria 07-18-2006 09:50 AM

Bash Script, calculate output.
Hey guys.

First of all, being a previous Microsoft Slave, being pretty good at VB, I got fed up and pretty much completely switched all my PC's to Kubuntu and my Server from Win2k to Ubuntu Server, I am slowly learning. but well luckily there is a great community to guide me. :-)

I'm running Ubuntu Server with lm-sensors installed.
For Cacti I would like to extract the raw temperature and Fan values without the fancy formatting from the sensors command.

So after a lot of searching and testing in /dev, /proc and /sys, I finally found that they are stored in /sys/bus/i2c/devices/9191-0290/

So to get my value I typed.

cat /sys/bus/i2c/devices/9191-0290/temp1_input

Now as you can probably guess my motherboard is not running 47500 degrees celcius, :-)

So after some searching on Google I found a bash script that does calculations.

c=`echo $a + $b | bc`
echo "$a + $b = $c"

But since it is not a fixed value I want to calculate I tried to modify the script.


a=cat /sys/bus/i2c/devices/9191-0290/temp1_input
c=`echo $a / $b | bc`
echo "$a / $b = $c"

But that gives me following error:


root@lnx1:~# ./showtemp
./showtemp: line 3: /sys/bus/i2c/devices/9191-0290/temp1_input: Permission denied
(standard_in) 1: parse error
 / 1000 =

So what am I doing wrong?


Hobbletoe 07-18-2006 10:00 AM

When you set your a variable, put the back ticks around the command that you are running (your cat command).


a=`cat /sys/bus/i2c/devices/9191-0290/temp1_input`

theNbomr 07-18-2006 10:01 AM

Try changing it to:

a=`cat /sys/bus/i2c/devices/9191-0290/temp1_input`

The backtics makes the stdout of 'cat' seem to be a comandline component, which can be assigned to a variable. It also groups the commandline into two operations.

--- rod.

zeitounator 07-18-2006 10:03 AM

This line in your script:

a=cat /sys/bus/i2c/devices/9191-0290/temp1_input
basically says: put the string 'cat' in variable a and then try to run the command /sys/bus/i2c/devices/9191-0290/temp1_input. To say you want to put the result of the full command "cat /sys/bus/i2c/devices/9191-0290/temp1_input" into the variable, you need to surround it by backticks like that:

a=`cat /sys/bus/i2c/devices/9191-0290/temp1_input`
That should get you rolling

Edited: I just saw I did not answer fast enough :)

eldaria 07-18-2006 10:12 AM

hehe 3 people with the same answer.. :)

And it worked, I tried the quotes but I used ' instead of `
Never knew the ` but now I know. :study:

Thanks a lot...

bigearsbilly 07-18-2006 10:19 AM

or ...

perl -ne 'print $_ / 1000.0' /sys/bus/i2c/devices/9191-0290/temp1_input

eldaria 07-18-2006 11:11 AM

Tried the last one, but it gives no output.


root@lnx1:~# perl -ne 'print $_ / 1000.0' /sys/bus/i2c/devices/9191-0290/temp1_input
root@lnx1:~# #

spirit receiver 07-18-2006 11:20 AM

I guess it should say

perl -ne 'print $_ / 1000.0' < /sys/bus/i2c/devices/9191-0290/temp1_input

eldaria 07-18-2006 01:13 PM

Same result as previous one.
But that's ok, the Bash script works. :)

eldaria 07-18-2006 01:19 PM

Actually with a bit of experimenting I found that the following also works:


echo `cat /sys/bus/i2c/devices/9191-0290/temp1_input` / 1000 | bc

bigearsbilly 07-19-2006 03:39 AM

oh well it was worth a try (perl)
I'm on solaris here so couldn't test it, apologies.
(actually both methods should work, with and without < )

ioerror 07-20-2006 09:59 AM

The perl example did work (presumably) but perl doesn't print a newline by default, so your prompt overwrote the output:


perl -ne 'print $_ / 1000.0, "\n"' ...
should work.

The shell can also do arithmetic itself with $(( ... )). Unfortunately bash is no use in this case as it can only handle integer arithmetic but more powerful shells like zsh can do floating point too, e.g.


print $(($(</sys/bus/i2c/devices/9191-0290/temp1_input)/1000.0))
Note the use of $(<...), which is equivalent to 'cat ...' except that the shell reads the file itself rather the spawning an instance of cat, so it is somewhat more efficient.

konsolebox 07-20-2006 10:52 AM

if you really insist doing this in pure bash you can do:


declare -i a=$(</sys/bus/i2c/devices/9191-0290/temp1_input)
echo $((a/1000)).$((a - a/1000*1000))

that should do some trick :)

konsolebox 07-20-2006 09:26 PM

and still a better and simpler approach:


declare -i a=$(</sys/bus/i2c/devices/9191-0290/temp1_input)
echo "${a:0:2}.${a:2}"

All times are GMT -5. The time now is 03:03 AM.