6

EDIT Thanks to pa4080 I added one line to the script below and now it works great. I don't exactly understand how, oh well.

I would like to make a cron job to adjust my brightness at different hours of the day. After doing some googling and trial and error I wrote the following bash script that works well:

#!/bin/bash
export DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}')

H=$(date +%H)

if (( 00 <= 10#$H && 10#$H < 07 )); then
    xrandr --output HDMI-1 --brightness .3 && xrandr --output HDMI-2 --brightness .3 && xrandr --output HDMI-3 --brightness .3
elif (( 07 <= 10#$H && 10#$H < 10 )); then
    xrandr --output HDMI-1 --brightness .5 && xrandr --output HDMI-2 --brightness .5 && xrandr --output HDMI-3 --brightness .5
elif (( 10 <= 10#$H && 10#$H < 19 )); then
    xrandr --output HDMI-1 --brightness .7 && xrandr --output HDMI-2 --brightness .7 && xrandr --output HDMI-3 --brightness .7
elif (( 19 <= 10#$H && 10#$H < 22 )); then
    xrandr --output HDMI-1 --brightness .5 && xrandr --output HDMI-2 --brightness .5 && xrandr --output HDMI-3 --brightness .5
elif (( 22 <= 10#$H && 10#$H < 23 )); then
    xrandr --output HDMI-1 --brightness .3 && xrandr --output HDMI-2 --brightness .3 && xrandr --output HDMI-3 --brightness .3
else
    echo "Error"
fi

Then I used crontab -e to add the following line:

0 * * * * /home/piney/screendimmer.sh

The cronjob is triggered but the script doesn't run. What am I doing wrong?

6

5 Answers 5

7

Cron provides limited set of environment variables by default [1]. To get xrandr to work through a Cron job, you should export [2] the value of the current user's $DISPLAY variable [3]. To do that add the follow line to the beginning of your script (or add it within the crontab file [4]):

export DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}')

References:


I liked the idea and already implemented it in my system. Here is my version of the above script:

#!/bin/bash

# While the user is not logged in == until the $DISPLAY variable is unset or empty
unset DISPLAY
while [ -z "$DISPLAY" ] || [ "$DISPLAY" == "" ]; do
        DISPLAY=$(w "$(id -un)" | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}' 2>/dev/null)
        if [ "$DISPLAY" == "" ]; then sleep 30; else export DISPLAY="$DISPLAY"; fi
done

brightness(){
        # Get the list of the active monitors automatically
        # To set this list manually use: OUT=( VGA-1 HDMI-1 HDMI-2 HDMI-3 )
        OUT=$(xrandr --listactivemonitors | awk 'NR!=1{print " "$NF" "}')
        # Adjust the brightness level for each monitor
        for current in "${OUT[@]}"; do xrandr --output "${current// /}" --brightness "$1"; done
}

if [ -z "${1+x}" ]; then  # If the scrip is called from Cron or CLI without an argument: 'brightness'
        H=$(date +%-H)
        if   ((  0 <= "$H" && "$H" <  7 )); then brightness ".5"
        elif ((  7 <= "$H" && "$H" < 10 )); then brightness ".6"
        elif (( 10 <= "$H" && "$H" < 19 )); then brightness ".7"
        elif (( 19 <= "$H" && "$H" < 22 )); then brightness ".6"
        elif (( 22 <= "$H" && "$H" < 24 )); then brightness ".5"
        else echo "Error"
        fi
else brightness "$1"    # If the scipt is called with an additional argument: 'brightness "<value>"'
fi
  • The script is able to get the list of the active monitors automatically. I've tested it with two monitors.

  • Nice idea is to place the executable file [5] in /usr/local/bin, thus it will be available also as shell command. Let's assume it is called brightness.

  • The script is able to use an arguments, which will override the default brightness values, for example: brightness .9.

  • While /usr/local/bin is not listed in the crontab's $PATH variable [1] [4] [6], the Cron jobs should use the full path:

    @hourly /usr/local/bin/brightness
    
  • Probably the @reboot Cron jobs will not work with the current version of the script [7].

2
5

Instead of writing cron jobs to manually change your display's brightness, you might want to have a look at redshift, a program that can do exactly this. It can be set up to track daylight at your location, and change both your display's brightness and color temperature to better match natural light.

Image illustrating the effect of redshift

Its main selling point is changing the color temperature (i.e., shifting the color more towards the red, which is where the name comes from), but it can also adjust brightness. You could configure it to do just brightness, if that's what you want.

The main advantage over the manual solution is that redshift changes color/brightness gradually, matched to the current daily cycle of your location, rather than in steps as with your cron approach. You can also switch the effect on/off rather easily; sending the process SIGUSR1 will toggle the effect. I made a keybinding that does killall -USR1 redshift to make this easily accessible.

There is another program of similar functionality called f.lux, which also supports Windows and MacOS and seems quite popular. I have no experience with it though; in particular I'm not entirely sure if it can change brightness in addition to color temperature.

5
  • This solution is valid @marcelm, besides Piney didn't informed ubuntu flavor and release. It's good to check if it will work on it. Does redshift work with scheduled times to change settings?
    – Redbob
    Sep 22, 2017 at 12:18
  • @Redbob As far as I know, redshift can not change settings on "scheduled times", but only track sunlight. It does this by calculating the position of the sun based on your location and time. So my answer is more of an alternative; an attempt at answering the OPs underlying desire rather than his exact question.
    – marcelm
    Sep 22, 2017 at 13:25
  • Great, @marcelm. Catch my vote... I installed in my computer (lubuntu), but it's seeking for 'geoclue2' and won't go ahead. My network is proxied, that's why I can run it.
    – Redbob
    Sep 22, 2017 at 13:43
  • I don't want a different colour temperature, otherwise I'd use one of the many programs that already do that.
    – Piney
    Sep 26, 2017 at 7:28
  • @Piney I explicitly addressed this in my answer: "You could configure it to do just brightness, if that's what you want."
    – marcelm
    Oct 1, 2018 at 19:53
5

You must type the path where xrandr is installed. Type command -v xrandr (or which xrandr) to know where it is installed. I suppose it's /usr/bin/xrandr, if it's installed by default.

So, edit yout crontab so:

#!/bin/bash

H=$(date +%k)

if   (( $H >  0 && $H <=  7 )); then
    /usr/bin/xrandr --output HDMI-1 --brightness .3 && /usr/bin/xrandr --output HDMI-2 --brightness .3 && /usr/bin/xrandr --output HDMI-3 --brightness .3
elif (( $H >  7 && $H <= 10 )); then
    /usr/bin/xrandr --output HDMI-1 --brightness .5 && /usr/bin/xrandr --output HDMI-2 --brightness .5 && /usr/bin/xrandr --output HDMI-3 --brightness .5
elif (( $H > 10 && $H <= 19 )); then
    /usr/bin/xrandr --output HDMI-1 --brightness .7 && /usr/bin/xrandr --output HDMI-2 --brightness .7 && /usr/bin/xrandr --output HDMI-3 --brightness .7
elif (( $H > 19 && $H <= 22 )); then
    /usr/bin/xrandr --output HDMI-1 --brightness .5 && /usr/bin/xrandr --output HDMI-2 --brightness .5 && /usr/bin/xrandr --output HDMI-3 --brightness .5
elif (( $H > 22 && $H <= 23 )); then
    /usr/bin/xrandr --output HDMI-1 --brightness .3 && /usr/bin/xrandr --output HDMI-2 --brightness .3 && /usr/bin/xrandr --output HDMI-3 --brightness .3
else
    echo "Error"
fi
3
  • This is not the issue here, because xrandr is actually located in /usr/bin/, but the default value of crontab's $PATH variable is /usr/bin:/bin.
    – pa4080
    Sep 22, 2017 at 8:36
  • thanks for the suggestion but it doesn't work :(
    – Piney
    Sep 26, 2017 at 7:28
  • Pinney, did you follow pa4080 instructions? I think they will help you. Otherwise, I installed Redshift as marcelm suggested, it works like a charm.
    – Redbob
    Sep 26, 2017 at 13:53
0

Another option would be to use xbacklight if you use xrand like this: xrandr --output HDMI-1 --brightness .3 && xrandr --output HDMI-2 --brightness .3 && xrandr --output HDMI-3 --brightness .3 this command will fail if you have VGA output.

You can install it with sudo apt install xbacklight. I use xbacklight with collaboration with redshift together they are the best.

1
  • Hi, Urosjarc, how we can use these features? Please elaborate your answer and give an example of usage.
    – pa4080
    Sep 29, 2017 at 8:35
0

echo $(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}') gives no output in Ubuntu 18.04. So I just did echo $DISPLAY inside the script and the output showed :0 then I added export DISPLAY=:0 and my cron job worked! My final script looks like this:

#!/bin/bash
# export DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}')
# echo $DISPLAY
export DISPLAY=:0
xrandr --output $1 --brightness $2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.