我有一个 systemd 计时器服务,它每 5 分钟运行一次脚本来检查显示器是否已关闭。如果已关闭,它会锁定屏幕。
但是我在用户和权限方面遇到了一些问题。似乎必须以 sudo 身份运行脚本才能查询显示器的电源状态,但这会导致 xsecurelock 需要 root 密码才能解锁屏幕。我该如何解决这个问题?
我应该说:我想保留这种方法并使用 xsecurelock,因为这在我的其他电脑上有效。需要 sudo 来查询电源状态似乎是这台电脑所特有的。
- 系统服务
Description=Check if Monitor is switched off and run xsecurelock
After=network.target
[Service]
User=dave
Environment=XAUTHORITY=/home/dave/.Xauthority
Environment=DISPLAY=:0
Type=simple
ExecStart=/home/dave/monitor_check.sh --debug
StandardOutput=journal
StandardError=journal
Restart=no
[Install]
WantedBy=multi-user.target
- 脚本
XSECURELOCK_SAVER=saver_xscreensaver
export XSECURELOCK_SAVER
echo "The value of XSECURELOCK_SAVER is: $XSECURELOCK_SAVER"
state=$(ddcutil getvcp D6 2>&1)
echo "$state"
sleep 2
if [[ "$state" == *"Display not found"* ]]; then
echo "Monitor is off, executing command..."
exec xsecurelock
break
else
echo "Display is found, nothing to do."
fi
这是违反直觉的。要修复运行脚本的 systemd 服务的权限,不需要更改 systemd 服务或脚本,而是创建 udev 规则:-
/etc/udev/rules.d/60-ddcutil-i2c.rules
子系统=="i2c-dev", 内核=="i2c-[0-9]*", ATTRS{class}=="0x030000", TAG+="uaccess"
子系统=="dri", 内核=="card[0-9]*", TAG+="uaccess"
因为ddcutil这个命令的权限是i2c的权限。
https://www.ddcutil.com/i2c_permissions/
希望这个发现对某些人有用,甚至是对制作屏幕保护程序 UI 的人有用。
该脚本可能相当容易移植到不同的显示器硬件上。其中D6不是 xrandr -query 中列出的显示器,而是命令列出的电源状态功能:-
ddcutil 功能
xrandr -query 用于获取 systemd 的 DISPLAY=:0 环境变量。在 xrandr 中它是 SCREEN,但在 systemd 中它是 DISPLAY
我认为屏幕保护程序 GUI 中没有这个功能的原因可能是 ddcutil 的功能输出以及(如果适用)不同制造商之间的电源状态差异太大。