X 从 cron 运行脚本时出现 BadAccess 错误

X 从 cron 运行脚本时出现 BadAccess 错误

我正在编写一个简单的脚本,该脚本应定期更改系统中所有屏幕的亮度。我发现为此我可以使用以下命令:

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。

相关内容