110 Colour-coded battery charge level and status in your bash prompt
Thursday 11th September, 2008
I still use a version of this script. The Linux kernel has changed somewhat so the script as it is below probably won't work. (Instead of /proc/acpi/battery/
, direct the script towards /sys/class/power_supply/
. And do make some other small changes.) I should update this.
Rob. April 2015.
I recently purchased a laptop, and having installed a proper OS, I found myself a little disappointed with the default battery meter provided by GNOME. Unless you mouse over the icon on the panel, it doesn't display exactly what charge level it is at. I am aware of the other options such as conky, gkrellm, screenlets, etc, but being the lazy sort, I consider it a long way to move your eyes! Since I'm the type who always has several terminals open, I thought it would be handy to display the charge level and status of the laptop battery in my shell prompt.
Firstly, I wrote a separate script to display the battery status. It's possible to write this into your ~/.bashrc as a function (which I also show how to do below), but I personally prefer a seperate script. The script had to fulfill certain requirements:
- The script had to display the charge level as a percentage.
- The script had to display it's results in colour, the reasons being
that:
- I like a colourful prompt, and
- if the charge level gets too low, it's easier to notice if the displayed charge level changes colour.
- The script also had to display the charge status, i.e. charging, discharging, or fully charged. After some experimentation I settled for a plus (+) for charging, a minus (-) for discharging, and an equals sign (=) for fully charged.
- I noticed in earlier revisions of the script that, due to the way /proc displays the charge level, the script could sometimes output a charge level greater than 100%, so I wanted to include a fix for that.
Here is the script I came up with:
#!/bin/bash # # battery status script # BATTERY=/proc/acpi/battery/BAT0 REM_CAP=`grep "^remaining capacity" $BATTERY/state | awk '{ print $3 }'` FULL_CAP=`grep "^last full capacity" $BATTERY/info | awk '{ print $4 }'` BATSTATE=`grep "^charging state" $BATTERY/state | awk '{ print $3 }'` CHARGE=`echo $(( $REM_CAP * 100 / $FULL_CAP ))` NON='\033[00m' BLD='\033[01m' RED='\033[01;31m' GRN='\033[01;32m' YEL='\033[01;33m' COLOUR="$RED" case "${BATSTATE}" in 'charged') BATSTT="$BLD=$NON" ;; 'charging') BATSTT="$BLD+$NON" ;; 'discharging') BATSTT="$BLD-$NON" ;; esac # prevent a charge of more than 100% displaying if [ "$CHARGE" -gt "99" ] then CHARGE=100 fi if [ "$CHARGE" -gt "15" ] then COLOUR="$YEL" fi if [ "$CHARGE" -gt "30" ] then COLOUR="$GRN" fi echo -e "${COLOUR}${CHARGE}%${NON} ${BATSTT}" # end of file
If you're going to use this script (at your own risk!), you should run it manually to test it before you continue. Your battery may be different, so if it doesn't work properly, have a look in /proc/acpi/battery and see if BAT0 should be BAT1 or something.
I use bash, so I had to edit my ~/.bashrc
file to change my
prompt. If you don't use bash, you'll have to figure out how to
modify the prompt yourself.
Remember to make a copy of your original ~/.bashrc
before making any changes to it!
Note that in order to display the output from an external script or command in your bash prompt, you need to precede the command by a "\$" and wrap the command in normal brackets. If you don't the script will only run once (when you first login) and after that the output will never change. Here is an example of how to insert the output from the script into your prompt:
# ~/.bashrc # ... (your other bashrc stuff) ... PS1="[ \$(/path/to/script/battery_status.sh) ] \$ " ... (more of your bashrc stuff) ...
Which should present a prompt that looks like this:
Fully charged:
[ 100% = ] $
Charging:
[ 97% + ] $
Discharging:
[ 45% - ] $
Discharging, level quite low:
[ 27% - ] $
Discharging, level very low:
[ 13% - ] $
For something a bit more informative, you could try this:
PS1="[ \$(/path/to/script/battery_status.sh) ] \u@\h:\w \$ "
which should look something like:
[ 64% + ] rob@khitai:~ $
Using a function instead of a script
If you want to use a function instead of a script, what you need to do is to write the text of the script into your ~/.bashrc as a function, e.g.
# ~/.bashrc # battery_status() { BATTERY=/proc/acpi/battery/BAT0 REM_CAP=`grep "^remaining capacity" $BATTERY/state | awk '{ print $3 }'` FULL_CAP=`grep "^last full capacity" $BATTERY/info | awk '{ print $4 }'` BATSTATE=`grep "^charging state" $BATTERY/state | awk '{ print $3 }'` ... (etc etc ... copy the remainder of the script) ... if [ "$CHARGE" -gt "30" ] then COLOUR="$GRN" fi echo -e "${COLOUR}${CHARGE}%${NON} ${BATSTT}" } ... (your other bashrc stuff) ... # Then call the function as you would any normal external script or command. PS1="[ $(battery_status) ] \$ " ... (more of your bashrc stuff) ...
All this of course leads to other things. You could include all sorts of non-standard* information in your prompt, such as CPU temperature, free space in your home partition, etc. There's lots of scope for experimentation. :-)
* By non-standard I mean data which is not natively provided by bash. To see list of natively-provided prompt customisations, the bash man page has a comprehensive list under the section "PROMPTING". Also, see the link below.