我正在编写一个简单的脚本,该脚本应定期更改系统中所有屏幕的亮度。我发现为此我可以使用以下命令:
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 分钟,然后打开它们):
#!/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()
我正在使用带有 Unity 桌面的 Ubuntu 16.04。