当运行与显示相关的命令时,类似的命令似乎xrandr
只有在作为本地用户运行时才起作用。
但是,当通过 udev 规则以本地用户身份运行脚本时:
SUBSYSTEM=="drm", ACTION=="change", RUN+="su -l --shell=/bin/bash -c /opt/echo-foo.sh chris"
定义echo-foo.sh
为:
#!/bin/bash
echo "foo"
准备udev
调试:
udevadm control --log-priority=debug
journalctl -f # tail the logs
udev
插入/拔出显示器时出现以下错误:
Starting 'su -l --shell=/bin/bash -c /opt/echo-foo.sh chris'
Sucessfully forked off '(spawn)' as PID #####
Process 'su -l --shell=/bin/bash -c /opt/echo-foo.sh chris' failed with exit code 1.
但是,从 root 开始,该命令可以工作。有没有正确的方法来做到这一点,而我遗漏了一些细节?
其他详情:
-rwxr-xr-x root root 3.3K ... /opt/echo-foo.sh
-- 3.3K:我的真实脚本被注释掉了。
答案1
为了允许命令xrandr
从“外部”影响您的会话,您需要为其提供一个有效的DISPLAY
环境变量,有时还需要一个XAUTHORITY
变量(取决于发行版和桌面环境),并且该命令需要能够访问套接字/tmp/.X11-unix/X<display number>
和X 会话 cookie 文件。
会话 cookie 文件的默认路径名是~/.Xauthority
;如果文件不在默认位置,那么您将需要该XAUTHORITY
变量来指示完整路径名。
X 服务器实际上并不检查与传入连接关联的用户 ID:它依赖于会话 cookie 文件通常受到保护的事实,因此只有 root 和文件所有者才能访问它。
换句话说,您可能su
根本不需要:只需
SUBSYSTEM=="drm", ACTION=="change", RUN+="/bin/sh -c 'DISPLAY=:0 XAUTHORITY=/home/chris/.Xauthority xrandr ...'"
root_squash
可能就足够了,除非您的主目录位于使用有效选项或类似选项导出的 NFS 共享上。
答案2
/bin/sh -c '...'
-- 是事情按预期工作所必需的。