Christopher Peterson

March 5, 2018

A Linux ACPI brightness control script



When I started using i3 window manager, I knew I’d basically have to re-engineer a number of desktop environment features myself around the bare window manager. One of these features is easy brightness control on my laptop.

The Arch Wiki has a great and in-depth page on this as it can be a very complex matter with a bunch of different ways to manage it on different hardware. Here! But after that, and if the ACPI method works for you, here is the script I came up with to manage it on Ubuntu!

ACPI brightness controls

So if you see something listed like this then you probably have a backlight you can interact with

$ ls -l /sys/class/backlight/**
/sys/class/backlight/some_backlight/:
total 0
-r--r--r-- 1 root root actual_brightness
-rw-r--r-- 1 root root bl_power
-rw-r--r-- 1 root root brightness
lrwxrwxrwx 1 root root device -> ../../card0-someSCREEN
-r--r--r-- 1 root root max_brightness
drwxr-xr-x 2 root root power
lrwxrwxrwx 1 root root subsystem -> ../../../../../../../class/backlight
-r--r--r-- 1 root root type
-rw-r--r-- 1 root root uevent

The files we’re interested in are brightness and max_brightness. Writing a value into brightness will… change the brightness! But one must be root to do this.

$ echo /sys/class/backlight/some_backlight/max_brightness
900
# Maybe make it sane eh
$ sudo bash -c 'echo 500 > brightness'

My script

So I made a script to do it! (Here is the current version of the script in my dotfiles, which may differ since the writing of this post)

#!/usr/bin/env bash
set -e

# Question: Under what circumstances could there be two backlight listings?
# If I had this, I would set it up to adjust each in turn maybe. But I don't.

# Usage
if [ "$#" -eq 0 ]; then
cat <<-EOF
Usage: $0 [command]
Increase or decrease screen brightness at hardware level by steps of 10% of
max, as determined by the values under /sys/class/backlight/**. Limit values
to the range of 0 to max_brightness.

up | Increase brightness by 10%
down | Decrease brightness by 10%
current | Report current brightness


This script needs root access - sudo is an option, but you may also consider
allowing your user to run the script without a password prompt e.g.:

# Append to /etc/sudoers
Cmnd_Alias BRIGHT_CMDS=/bin/path/bright up, /bin/path/bright down
username ALL=(root) NOPASSWD: BRIGHT_CMDS
EOF
exit 1
fi

# Gather information
backlight_dir='/sys/class/backlight'
device_dir=$(ls "${backlight_dir}" | head -n 1)
if [ -z "$device_dir" ]; then
echo 'No backlight hardware is listed in /sys/class/backlight! Quitting.'
exit 1
fi
device_dir="${backlight_dir}/${device_dir}"
brightness_file="${device_dir}/brightness"
curr_brightness=$(cat "${brightness_file}")
max_brightness=$(cat "${device_dir}/max_brightness")

if [ "$1" == 'current' ]; then
echo $( echo "(${curr_brightness} / ${max_brightness}) * 100" | bc -l) \
| cut -d'.' -f 1
else
direction=$1

# Calculate
step=$(( $max_brightness / 10 ))
if [ $direction == 'up' ]; then
new_brightness=$(( $curr_brightness + $step ))
elif [ $direction == 'down' ]; then
new_brightness=$(( $curr_brightness - $step ))
else
echo 'Argument $1 must be either "up" or "down". Quitting.'
exit 1
fi
# Limit range
if [ "$new_brightness" -gt "$max_brightness" ]; then
new_brightness="$max_brightness"
fi
if [ "$new_brightness" -lt 0 ]; then
new_brightness=0
fi

# "Do it" - the emperor
echo $new_brightness > "${brightness_file}"
fi

Usage

# Brightness up
$ sudo bright up

# Brightness down
$ sudo bright down

# Report current brightness level
$ bright current

If you’re going to bind this to some key combo, you may want to allow this to sudo without a password (as securely as possible).

# `sudo visudo` and add these lines to your sudoers
Cmnd_Alias BRIGHT_CMDS=/path/to/this/script/bright up, /path/to/this/script/bright down
your_user ALL=(root) NOPASSWD: BRIGHT_CMDS

Here is my binding for i3wm

# Brightness controls
bindsym XF86MonBrightnessUp exec sudo /path/to/this/script/bright up; exec notify-send -t 1 "Brightness: $(/path/to/this/script/bright current)%"
bindsym XF86MonBrightnessDown exec sudo /path/to/this/script/bright down; exec notify-send -t 1 "Brightness: $(/path/to/this/script/bright current)%"

So there you go!

Brightness icon in featured image by Elegant Themes