Laptop Battery Info With Bash, sed, and AWK
My Ubuntu 11.04 system recently begun showing signs of Redmondism, freezing up from time to time, and also breaking software with updates. When the MongoDB server refused to start after I asked it politely, I’ve decided to reinstall Arch Linux as was my original intent anyway. The pure geek awesomeness is finally back on my laptop.
So, while all the packages were being installed, I god a bit bored, and decided to make a simple battery charge level info script. The script simply displays the amount of charge left in the battery.
On Linux, the information about the battery is available throgh a virtual text file in the /proc directory. On my system, the actual path is /proc/acpi/battery/BAT0. If you have more than one battery, you’d have BAT1, BAT2, etc. Inside this directory, there are two files that are of interest: state, and info. The info file contains the following:
[foxbunny@megafox ~]$ cat /proc/acpi/battery/BAT0/info
present: yes
design capacity: 4400 mAh
last full capacity: 4220 mAh
battery technology: rechargeable
design voltage: 11100 mV
design capacity warning: 440 mAh
design capacity low: 133 mAh
cycle count: 0
capacity granularity 1: 44 mAh
capacity granularity 2: 44 mAh
model number: DELL 8NH5512
serial number: 5590
battery type: LION
OEM info: SMP
And the state file contains the following:
[foxbunny@megafox ~]$ cat /proc/acpi/battery/BAT0/state
present: yes
capacity state: ok
charging state: charging
present rate: 634 mA
remaining capacity: 4154 mAh
present voltage: 12588 mV
What we are interested in are the design capacity field from the info file, and remaining capacity from the state file. So let me show you how I extracted the info.
First, to extract one line, you would do this:
[foxbunny@megafox ~]$ cat /proc/acpi/battery/BAT0/info \
> | grep 'design capacity:'
design capacity: 4400 mAh
We then need to extract just the numerical part.
[foxbunny@megafox ~]$ cat /proc/acpi/battery/BAT0/info \
> | grep 'design capacity:' | sed 's/[a-z: ]\+//gI'
4400
A bit of simple sed that case-insensitively removes letters, space, and colon characters from the string. The global g flag is there because otherwise sed would match only the characters preceding the numbers, but would leave those that come after intact. With the g flag, it would match any number of times until it is out of characters to match. Unlike most regexes in different programming languages, sed’s regex requires you to use backslash in front of +.
So, let’s put this into a script:
#!/bin/bash
REM=`cat /proc/acpi/battery/BAT0/state \
| grep remaining \
| sed 's/[a-z: ]\+//gI'`
TOT=`cat /proc/acpi/battery/BAT0/info \
| grep 'design capacity:' \
| sed 's/[a-z: ]\+//gI'`
Now we have variables REM (remaining) and TOT (total). Let’s calculate the percentage of REM in TOT. The formula is REM/TOT*100, but how do we do this in a script? We will use AWK:
PERCENTAGE=`echo "${REM} ${TOT}" \
| awk '{print $1/$2*100}'`
Awk divides a line into fields. We therefore echo REM and TOT separated by a single space, which then AWK treats like two fields and assigns them to $1 and $2 variables respectively. We can then take advantage of AWK’s math functionality and calculate what we need.
Finally, we echo the results in a slightly more palatable form:
echo remaining power: $PERCENTAGE%
Executing the script, it may show you something like:
remaining power: 95.8636%




