web-dev-qa-db-fra.com

xrandr en tant que root ne peut pas trouver d'affichages

La règle suivante appelle mon script lorsque je docke ou désancre mon 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"

C'est le script qui s'appellera:

# /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 &

Et le script appelé ensuite fait quelque chose avec xrandr.

Le fait est que je peux exécuter think-dock on en tant qu'utilisateur (mu) et que cela fonctionne. Je peux Sudo -i et exécuter think-dock-hook on et cela fonctionne aussi. Mais quand je laisse udev l’exécuter, il obtient juste l’erreur suivante de xrandr:

# output of bash -x think-dock on
+ xrandr --output LVDS1 --auto
Can't open display

Maintenant, si j'appelle xrandr à partir de mon Sudo -i Shell, je reçois:

No protocol specified
No protocol specified
Can't open display :0

Cependant, si je fais su -c xrandr mu à partir de mon Sudo -i Shell, j'obtiens le résultat attendu.

Donc, je ne comprends pas vraiment, le script appelé à partir de udev échoue.

9
Martin Ueding
  • xrandr a besoin de savoir de quel écran vous parlez, généralement via la variable d'environnement DISPLAY
  • root (qui dev s'exécute en tant que) n'a pas de valeur par défaut DISPLAY set; même s'il/elle l'a fait, su -c ne préserve pas l'environnement par défaut
  • Donc, transmettez-le explicitement à bash, et cela devrait résoudre votre problème, par exemple:

    su -c "DISPLAY=:0.0 bash -x /usr/bin/think-dock $setto" "$user"
    
7
ish