作为 root 的 xrandr 找不到显示器

Mar*_*ing 9 xrandr root

当我停靠或取消停靠我的 ThinkPad 时,我有以下规则调用我的脚本:

# /lib/udev/rules.d/81-thinkpad-dock.rules
KERNEL=="dock.0", ATTR{docked}=="0", RUN+="/usr/bin/think-dock-hook off"
KERNEL=="dock.0", ATTR{docked}=="1", RUN+="/usr/bin/think-dock-hook on"
Run Code Online (Sandbox Code Playgroud)

这是将被调用的脚本:

# /usr/bin/think-dock-hook
# Find the user who is currently logged in on the primary screen.
user="$(who -u | grep -F '(:0)' | head -n 1 | awk '{print $1}')"
su -c "bash -x /usr/bin/think-dock $setto" "$user" >> /root/think-dock.log 2>&1 &
Run Code Online (Sandbox Code Playgroud)

然后调用的脚本对xrandr.

问题是我可以think-dock on作为我的用户 ( mu)运行并且它可以工作。我sudo -i能跑think-dock-hook on,它也能用。但是当我让它udev运行它时,它只是从以下错误中得到以下错误xrandr

# output of bash -x think-dock on
+ xrandr --output LVDS1 --auto
Can't open display
Run Code Online (Sandbox Code Playgroud)

现在,如果我xrandr从我的sudo -ishell 中调用,我会得到:

No protocol specified
No protocol specified
Can't open display :0
Run Code Online (Sandbox Code Playgroud)

但是,如果我su -c xrandr musudo -ishell 中执行此操作,则会得到预期的输出。

所以我不太明白,从调用的脚本udev失败了。

ish*_*ish 7

  • xrandr需要知道你在谈论哪个显示,通常是通过DISPLAY环境变量
  • rootudev运行的方式)没有默认DISPLAY设置;即使他/她这样做,su -c默认情况下也不会保护环境
  • 因此,将它明确传递给 bash,这应该可以解决您的问题,例如:

    su -c "DISPLAY=:0.0 bash -x /usr/bin/think-dock $setto" "$user"
    
    Run Code Online (Sandbox Code Playgroud)