8

I have a bash script that I use to adjust my monitor brightness that uses xrandr --verbose to get the current brightness. It works fine, but using xrandr is kind of slow on my machine, as you can see here:

[PROMPT REDACTED]$ time xrandr --verbose
# xrandr output omitted for brevity
real    0m0.976s
user    0m0.003s
sys     0m0.002s

This outputs lots of information that I don't need, in addition to taking almost a full second. The only line out of the output that I actually need is Brightness: X. I am currently using this line to get the value from it:

BRIGHTNESS=`xrandr --verbose | grep -i brightness | cut -f2 -d ' ' | head -n1`

Side note: head is called at the end because I have 2 monitors, so I end up with 2 values, but only need 1, since I am keeping them both at the same brightness.

Since I only need that one line from xrandr --verbose, I was wondering if there is a way I could "lazily" evaluate it, by doing something like:

  • Stopping xrandr outputting once it reaches that line
  • Ignoring the rest of the output from xrandr once I have read that line
  • Something else?

I realize bash may not be the language best suited for this, so I am open to solutions in other languages as well.

8
  • Can you use one of xbacklight -get or cat the appropriate file in /sys/class/backlight?
    – drs
    Commented Aug 18, 2014 at 16:30
  • I have just installed xbacklight, and xbacklight -get outputs No outputs have backlight property. I have no files in /sys/class/backlight either.
    – gla3dr
    Commented Aug 18, 2014 at 16:36
  • xrandr executes in 0.084s for me :x
    – Populus
    Commented Aug 18, 2014 at 21:56
  • @Populus xrandr or xrandr --verbose? Just xrandr only takes about ~.080s for me
    – gla3dr
    Commented Aug 18, 2014 at 22:01
  • xrandr is open source. It shouldn't be terribly difficult to modify the source to make your own program that only queries the brightness. That's sort of the nuclear option, though. Commented Aug 18, 2014 at 22:28

6 Answers 6

9

You can use awk to remove some pipelines (processes) and to only read the file until encountering the first instance of Brightness:

xrandr --verbose | awk '/Brightness/ { print $2; exit }'
7
  • Looks like awk is indeed a little faster than grep and cut. Thanks!
    – gla3dr
    Commented Aug 18, 2014 at 17:36
  • Combined with the stdbuf -o0 trick in my answer, this is the fastest solution here. +1
    – user26112
    Commented Aug 18, 2014 at 22:21
  • @paraxor - not anymore. By my tests the sed solution in my own answer and the awk solution here present no difference in execution time - and I also have two displays, so the q makes a significant difference. Each runs at .03 to .04 seconds at every execution - and the addition of stdbuf only slows them down. But xgamma is faster still.
    – mikeserv
    Commented Aug 18, 2014 at 22:47
  • @mikeserv adding stdbuf seems to be crucial on my machine. Using @jasonwryan's solution exactly (no stdbuf), I got real 0m0.728s. Adding stdbuf to it gave me real 0m0.126s. However, using your sed solution along with stdbuf as opposed to awk seems to consistently give me another .006s.
    – gla3dr
    Commented Aug 19, 2014 at 15:05
  • 1
    @mikeserv That was in the terminal and using awk.
    – gla3dr
    Commented Aug 19, 2014 at 15:09
7

Let's try and stop and ignore upon the first find of brigthness. From grep man page:

 -m NUM, --max-count=NUM
          Stop  reading  a  file after NUM matching lines.

This is my final version. Note that we don't even need the head:

BRIGHTNESS=`xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '`
1
  • This is exactly what I was looking for, thanks. It's a little faster now. Not quite as fast as I had hoped though.
    – gla3dr
    Commented Aug 18, 2014 at 16:53
6

In addition to @LatinSuD's suggestion of using grep's -m flag to stop reading after a match, you can adjust the size of xrandr's stdout buffer with a tool like stdbuf like so:

BRIGHTNESS=`stdbuf -o0 xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '`

This can give you a significant speed increase:

$ cat brightness
xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '

$ time sh brightness > /dev/null
sh brightness > /dev/null  0.00s user 0.00s system 1% cpu 0.485 total

$ cat brightness_nobuffer
stdbuf -o0 xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '

[ para ~ . ]$ time sh brightness_nobuffer > /dev/null
sh brightness_nobuffer > /dev/null  0.01s user 0.01s system 10% cpu 0.130 total
0
2

The slowest step is: xrandr --verbose. So if you didn't have to fetch brightness using xrandr --verbose every time you try adjusting your brightness, the problem will be solved.

This can be achieved by the following workflow:

  1. Export the current brightness one-time (preferably, at start-up) using: echo `xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '` > brightness.txt
  2. And every time you need the brightness read it from brightness.txt
  3. And every time you update the brightness also update the value at brightness.txt

For example this is how I update my brightness:

#!/bin/bash

# BRIGHT=`xrandr --verbose | grep -m 1 -i brightness | cut -f2 -d ' '`

BRIGHT=`cat brightness.txt`

if [ "$1" = '+' ]; then
    NEWBRIGHT=$(echo "$BRIGHT + 0.05" | bc)
    if [ "$(echo "$NEWBRIGHT > 1.0" | bc)" -eq 1 ]; then
        NEWBRIGHT='1.0'
    fi
elif [ "$1" = '-' ]; then
    NEWBRIGHT=$(echo "$BRIGHT - 0.05" | bc)
    if [ "$(echo "$NEWBRIGHT < 0.0" | bc)" -eq 1 ]; then
        NEWBRIGHT='0.0'
    fi
fi

xrandr --output eDP-1 --brightness "$NEWBRIGHT"
echo "${NEWBRIGHT}" > brightness.txt
1

I suggest you install the xbacklight program.

Of course, if your hardware does not support it, this is not an option. So you must resort to the software adjustment as you have been doing:

man xrandr 2>/dev/null |
grep '^ *--brightness' -A8
   --brightness brightness
          Multiply the gamma values on the  crtc  cur‐
          rently  attached  to the output to specified
          floating value. Useful for overly bright  or
          overly  dim  outputs.   However,  this  is a
          software only modification, if your hardware
          has  support  to actually change the bright‐
          ness, you will probably prefer to use xback‐
          light.

It would appear that the brightness settting is nothing more than a multiplier for the RGB gamma values of your display. As such, it might make more sense - or, at least, it may be easier - if you instead directly affected that with xgamma.

xgamma
-> Red  1.000, Green  1.000, Blue  1.000

xgamma -gamma .7
-> Red  1.000, Green  1.000, Blue  1.000
<- Red  0.700, Green  0.700, Blue  0.700

In the same vein as many other answers you can quit the input with sed as soon as you encounter a Brightness string like:

xrandr --verbose | sed '/Br/!d;s/.* //;q'

That deletes all lines before the first occurrence of the Br string. When it finds one it then removes everything up to and including the last <space> from the line before immediately quitting the input. So all that remains in a case of 100% brightness is, for instance:

echo "<$(xrandr --verbose | sed '/Br/!d;s/.* //;q')>"
<1.0>

It would be far better though if you could get a valid EDID on your output and directly affect its backlight with the following tool:

man xbacklight 2>/dev/null | 
sed '/^ *SYNOPSIS/,/^ *-inc/!d;//c\\'

       xbacklight [-help]  [-display display] [-get] [-set
       percent] [-inc percent] [-dec percent]

DESCRIPTION
       Xbacklight  is used to adjust the backlight bright‐
       ness where supported. It finds all outputs on the X
       server  supporting backlight brightness control and
       changes them all in the same way.

       -get   Print out the current  backlight  brightness
              of  each  output  with  such  a control. The
              brightness is represented as a percentage of
              the maximum brightness supported.

       -set percent
              Sets each backlight brightness to the speci‐
              fied level.

It is apparently already installed on my machine because, at some point I installed...

pacman -Qo /usr/bin/xbacklight
/usr/bin/xbacklight is owned by xorg-xbacklight 1.2.1-1

...^that package.

10
  • See second comment on question. Any ideas on how to solve that issue?
    – gla3dr
    Commented Aug 18, 2014 at 21:01
  • I'm sorry @gla3dr - I did not see that. I'll look into it. It maybe to do with xset and DPMS. Also - what kind of connection do you have between monitor/computer? HDMI/DVI?
    – mikeserv
    Commented Aug 18, 2014 at 21:03
  • I have Monitor -> DVI -> VGA adapter -> Computer
    – gla3dr
    Commented Aug 18, 2014 at 21:05
  • @gla3dr Oh, then, yes, I have an idea how you might solve it. I suggest you do Monitor -> DVI -> Computer - is this possible?
    – mikeserv
    Commented Aug 18, 2014 at 21:07
  • Looks like I was slightly wrong about that. I have 2 DVIs (one from each monitor) going into a DMS-59 Y-adapter. That is what is going into my computer.
    – gla3dr
    Commented Aug 18, 2014 at 21:30
0

As xbacklight was not working for me I adapt previous answer to make a script which could be called as keyboard shortcut :

#!/bin/bash
bright=$(xrandr --verbose | awk '/Brightness/ { print $2; exit }')
case $1 in
up)
xrandr --output eDP-1 --brightness $(echo $bright+0.1 |bc -l)
;;
down)
xrandr --output eDP-1 --brightness $(echo $bright-0.1 |bc -l)
;;
*)
echo error
exit 1
;;
esac

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .