Я пишу простой скрипт, который должен периодически менять яркость всех экранов в системе. Я понял, что для этого я могу использовать следующую команду:
xrandr --output {display name} --brightness {float in a range [0.0,1.0]}
Сначала я хотел использовать xbacklight, но оказалось, что он не может контролировать яркость всех экранов, поэтому я переключился на xrandr.
Когда я запускаю эту команду из терминала, она работает нормально, но затем я попытался запланировать ее для crontab, чтобы она периодически запускалась, сначала она вообще не работала, но потом я обнаружил, что мне нужно предоставить $DISPLAY env
переменная в cron, чтобы скрипт знал, где искать X.
Кажется, что он работает сейчас, но не совсем нормально, потому что иногда он дает ошибку, подобную этой:
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 131 (XInputExtension)
Minor opcode of failed request: 57 ()
Serial number of failed request: 18
Current serial number in output stream: 19
И я не могу понять, почему эта ошибка возникает и что делать, чтобы ее исправить?
Вот содержимое моего файла crontab:
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/user
DISPLAY=:0
XAUTHORITY=/home/user/.Xauthority
0 * * * * python3 /home/user/script.py > /home/user/scriptLog 2>&1
И сценарий (он запускается каждый час, сначала выключает клавиатуру и все экраны на 5 минут, а затем поворачивает их on):
#!/usr/bin/env python3
import time
import os
import sched
SEC_PER_HOUR = 60 * 60
MIN_PER_HOUR = 60
SEC_PER_MIN = 60
DEVICE_ACTIVE = 139
dur = 5
def xinput_set_prop(devices, prop, val):
for id in devices:
os.system("xinput set-prop {} --type=int --format=8 {} {}".format(id, prop, val))
def xrandr_set_brightness(devices, val):
for id in devices:
os.system("xrandr --output {} --brightness {}".format(id, val))
cur_t = time.time()
if cur_t / SEC_PER_HOUR - cur_t // SEC_PER_HOUR < dur / MIN_PER_HOUR:
keyboard_ids = [line.replace("\n", "") for line in os.popen("""xinput list | sed -rn 's/.*id=//; s/\s+.*slave\s+keyboard.*//p'""")]
monitor_ids = [line.replace("\n", "").split(" ")[-1] for line in os.popen("""xrandr --listmonitors""")]
xrandr_set_brightness(monitor_ids, 0.01)
xinput_set_prop(keyboard_ids, DEVICE_ACTIVE, 0)
run_t = cur_t // SEC_PER_HOUR * SEC_PER_HOUR + dur / MIN_PER_HOUR + dur * SEC_PER_MIN
del_t = run_t - cur_t
s = sched.scheduler(time.time, time.sleep)
s.enter(del_t, 1, xinput_set_prop, argument=(keyboard_ids, DEVICE_ACTIVE, 1))
s.enter(del_t, 1, xrandr_set_brightness, argument=(monitor_ids, 1.0))
s.run()
Я использую Ubuntu 16.04 с рабочим столом Unity.