My system is really limited and lacking what some would consider dealbreaking features.
Linux is a fine sturdy OS, but by default some of the functionality can feel a bit
too basic. Like the battery charge monitoring, wouldn't it be nice to see a clean
percentage, rather than a huge charge value?
Thankfully linux gives us some text based IO, (sysfs, /sys), that can be dealt with
using standard posix shell scripts. So I decided to write some scripts to
improve my current situation with no good battery meter, or backlight power control.
Below are some quick examples of how to interact with /sys to control linux hardware.
Linux sysfs contains an abundance of data about the hardware, also you can change
certain variables, like the backlight script you will at the end of this article.
Here's an easy one, some gpu and display related files, in addition to what
you can already find in /dev/dri.
gpu_displays.sh:
#!/bin/sh
find /sys/class/drm
Ok that was weak, here is something actually useful.
let's use our friend bc to print out the current battery charge as a percentage.
We previously learned about how to use bc, a powerful math command.
see the shell_math article for more info.
battery_charge.sh:
#!/bin/sh
#
# FIXME: missing support for multiple batteries
#
if [ ! -e "/sys/class/power_supply" ]; then
echo "/sys/class/power_supply not found, is sysfs mounted?"
exit -1
fi
#PLUGGED_IN=$(cat /sys/class/power_supply/AC/online)
CHARGE_FULL=$(cat /sys/class/power_supply/BAT0/charge_full)
CHARGE_NOW=$(cat /sys/class/power_supply/BAT0/charge_now)
CHARGE_STATUS=$(cat /sys/class/power_supply/BAT0/status)
CHARGE_PERCENT=$(echo "scale=5; $CHARGE_NOW / $CHARGE_FULL * 100" | bc | sed -E -n "s/(..\....).*/\1/p")
echo "$CHARGE_STATUS: $CHARGE_PERCENT%"
This last script will let us set backlight value instead of wasting energy at maximum.
backlight_power.sh:
#!/bin/sh
#
# FIXME: only tested on intel_backlight driver,
# it may or may not work with multiple backlights/displays
#
if [ ! -e "/sys/class/backlight" ]; then
echo "/sys/class/backlight not found, is sysfs mounted?"
exit -1
fi
print_usage() {
echo ""
echo " print or set the power of backlight"
echo ""
echo "backlight_power usage:"
echo " backlight_power -- print current power by percent"
echo " backlight_power <percent> -- set backlight by percent"
echo ""
echo ""
exit -1
}
if [ "$1" = "" ]; then
SET_POWER=0
else
CHECK_PERCENT=$(echo $1 | sed "s/[0-9]//g")
if [ "$CHECK_PERCENT" != "" ]; then
echo "expected an integer (0 .. 100) percentage"
print_usage
fi
if [ $1 -gt 100 ]; then
SET_POWER=100
elif [ $1 -le 0 ]; then
SET_POWER=1
else
SET_POWER=$1
fi
fi
BACKLIGHTS=$(find /sys/class/backlight -mindepth 1 -maxdepth 1)
IFS=$'\n'
for BACKLIGHT in $BACKLIGHTS; do
POWER_MAX=$(cat $BACKLIGHT/max_brightness)
POWER_NOW=$(cat $BACKLIGHT/brightness)
if [ "$SET_POWER" = "0" ]; then
POWER=$(echo "scale=5; $POWER_NOW / $POWER_MAX * 100" | bc | sed -E -n "s/(..\....).*/\1/p")
echo "$BACKLIGHT: $POWER%"
else
POWER=$(echo "scale=5; $POWER_MAX * $SET_POWER / 100" | bc | sed -E -n "s/(.*)\..*/\1/p")
echo "setting $BACKLIGHT/brightness to: $POWER, $SET_POWER% "
printf "$POWER" > $BACKLIGHT/brightness
printf "($POWER) > $BACKLIGHT/brightness"
fi
done