我正在尝试从根会话执行脚本,但遇到了一些问题。我将阐述这个问题:
我有一个脚本,它以普通用户“kolterdyx”的身份执行某些任务,并以 root 的身份执行其他任务sudo
。此脚本的作用是旋转屏幕并自动更新触摸屏校准矩阵。我花了大约一周的时间排除故障,我得出的脚本如下:
/home/kolterdyx/.cargo/bin/gnome-randr modify HDMI-1 --rotate "$1"
rule='ATTRS{idVendor}=="27c0", ATTRS{idProduct}=="0818", ENV{LIBINPUT_CALIBRATION_MATRIX}='
right='"0 -1 1 1 0 0"'
left='"0 1 0 -1 0 1"'
inverted='"-1 0 1 0 -1 1"'
normal='"1 0 0 0 1 0"'
case "$1" in
left )
RULE="$rule$left"
;;
right )
RULE="$rule$right"
;;
inverted )
RULE="$rule$inverted"
;;
normal )
RULE="$rule$normal"
* )
echo "You need to pass an argument"
exit
;;
esac
sudo bash -c "echo '$RULE' > /etc/udev/rules.d/99-calibration.rules"
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo bash -c 'echo 1-1 > /sys/bus/usb/drivers/usb/unbind'
sudo bash -c 'echo 1-1 > /sys/bus/usb/drivers/usb/bind'
运行此程序的系统是 Raspberry Pi OS,我安装时没有桌面,然后安装了 Gnome,默认情况下它使用 Wayland 和 Gnome-Shell。这引发了麻烦,即试图通过 SSH 在非 X11 环境中执行 X11 任务(因为我无法将键盘连接到 Raspberry Pi)。
我设法使该脚本运行,但是只有当我以 身份kolterdyx
直接从用户 shell 运行它时它才有效。sudo -u kolterdyx
或者runuser -u kolterdyx
以任何其他用户的身份运行它都不起作用,我收到的错误如下:
Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
发生这种情况是因为第一行是来自gnome-randr-rust
。出于某种原因,如果我以 root 身份运行它,kolterdyx
它会正常工作,但如果我以 root 身份运行它,无论是否使用sudo -u kolterdyx
,我都会收到上述错误。 sudo 不是应该让目标用户运行该命令吗?有什么区别,我如何才能让命令以我的用户身份从 root 用户运行?
答案1
程序可以通过几种方式找到您的 D-Bus 会话总线:
明确设置 $DBUS_SESSION_BUS_ADDRESS。如果您不使用 systemd 或者您的发行版未启用“用户总线”模型,则这是主要方法;在这些情况下,通常每次登录时都会选择一个随机地址。
$XDG_RUNTIME_DIR/bus 下的一个众所周知的路径。这是 systemd 式的方法,其中每个 UID 只有一个会话总线,并且始终位于半固定的每个 UID 位置。
基于 X11 $DISPLAY 自动启动;这是 D-Bus 早期遗留的机制,现在大多数发行版都避免使用(尤其是因为它依赖于 X11)。不过,作为最后的后备方案,它最终会出现那些误导性错误消息。
因此,您需要设置上述两个环境变量之一。在 systemd 环境中,XDG_RUNTIME_DIR 是更简单的选择,因为它几乎总是设置为该值,/run/user/$UID
并且您可以在脚本中安全地对该格式进行硬编码 - 它不仅会覆盖 D-Bus,还会覆盖 Wayland 套接字地址以及围绕该路径建立的各种其他组件。否则,您需要让您的桌面会话在启动时将其 DBUS_SESSION_BUS_ADDRESS 写入文件,然后脚本将读取该文件。
(事实上,有了 systemd,最简单的方法可能是自动找到总线地址并在会话内直接生成命令,并拥有所有必要的环境。)systemd-run --user -M [email protected]
顺便说一句,GNOME 不是已经内置了通过 iio-sensor-proxy 检测屏幕方向的支持吗?