从 Udev 以本地用户身份 su 的正确方法是什么?

从 Udev 以本地用户身份 su 的正确方法是什么?

当运行与显示相关的命令时,类似的命令似乎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 '...' 

-- 是事情按预期工作所必需的。

相关内容