Tengo un script que se ejecuta a través de cron para cambiar el fondo de escritorio. Puedo hacer que funcione exportando la variable DISPLAY.
Pero el problema que me preocupa es que el script debería funcionar en todos los sistemas. ¿Cómo encontrar el valor de DISPLAY establecido por el servidor X sin usar $ DISPLAY?
Entonces, ¿cómo puedo encontrar el valor correcto para DISPLAY
mediante programación. Puedo hacerlo funcionar solo cuando DISPLAY=:1
. Establecerlo en ":0"
hace que el script salga con
No protocol specified
Cannot open display.
No puedes estar seguro. Tienes que hacer suposiciones.
Imagina que eres cron
y te enfrentas al peor de los casos por un segundo: hay varios usuarios conectados y cada usuario está ejecutando varias sesiones X. Tendrás que adivinar el usuario (bastante fácil, estamos ejecutando su crontab) y una de las sesiones X de ese usuario.
Si queremos asumir que el usuario está ejecutando una y solo una sesión X de un tty, y obtener el valor $DISPLAY
de esa sesión, podemos usar w
:
USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
user tty1 16:32 7:15 0.21s 0.19s -zsh
user tty2 :1 15:52 48:13 2:17 0.08s /sbin/upstart
user pts/3 :1 16:19 0.00s 0.66s 0.00s w
Por ejemplo, aquí he iniciado sesión en tty1, en tty2 (donde estoy ejecutando una sesión X) y en pts/3 (el terminal desde el que estoy ejecutando el comando).
Con un poco de análisis:
% w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}'
:1
Entonces, suponiendo todo lo anterior:
0 0 * * * DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}') command
Hará que cron
ejecute command
con $DISPLAY
configurado en la primera sesión X que se ejecuta en un valor de tty $DISPLAY
encontrado para el usuario.
Para una discusión más detallada, consulte https://unix.stackexchange.com/questions/17255/is-there-a-command-to-list-all-open-displays-on-a-machine
Simplemente enumeraré la información relevante de esa respuesta aquí:
Parece que hay dos formas simples de encontrar las instancias del servidor X que se ejecutan en su sistema.
w
:
El comando w
enumera todas las pantallas abiertas. Luego puede usar awk
para filtrar la información que necesita. Los valores debajo de FROM
son los valores correspondientes a DISPLAY
.
[email protected]:[/tmp/.X11-unix]????????
$ w
21:18:24 up 3:39, 4 users, load average: 0.31, 0.27, 0.30
USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
ashhar tty2 :1 17:40 3:39m 6:11 0.08s /usr/bin/dunst
ashhar pts/0 :1 17:41 3:36m 0.13s 0.05s vim .i3/config
ashhar pts/1 :1 18:07 0.00s 1.44s 0.00s w
ashhar pts/2 :1 18:15 9:59 0.79s 0.79s bash
Las pantallas locales corresponden a un socket en /tmp/.X11-unix
, por lo que simplemente podemos hacer:
cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done