Detectar sesión X en un script bash (.bashrc, etc.)

16

Recientemente lo puse xset b offen mi .bashrc. Ahora estoy molesto por el error que aparece cuando inicio sesión a través de tty o ssh, es decir, fuera de la sesión X.

Lo primero que se me ocurrió fue [[ -z "$SOME_VAR" ]] && xset b off(bueno, resulta que la variable de prueba que se establece frente a estar vacía es una pregunta diferente). ¿Pero cuál SOME_VAR es el correcto?

Así que diferto la setsalida de tty y la salida de urxvt setpara ver qué variables están establecidas en X y las que faltan en tty. Como era de esperar, hubo muchas diferencias (enumerando solo las que me parecieron relevantes):

  • DESKTOP_SESSION
  • DISPLAY
  • GDMSESSION
  • SESSION_MANAGER
  • WINDOWID
  • WINDOWPATH
  • XAUTHORITY
  • XDG_SESSION_COOKIE
  • XDG_CONFIG_DIRS
  • XDG_DATA_DIRS
  • XDG_MENU_PREFIX

¿Cuál es el más correcto y universal para probar para detectar si estoy en una sesión X o no? ¿Algo que funcione en tantas distribuciones, plataformas y entornos de escritorio como sea posible?

¿O hay una forma aún mejor que probar las variables de entorno?

Alois Mahdal
fuente

Respuestas:

8

Una manera simple y efectiva de probar que su servidor de visualización está disponible y es válido es probarlo con xhost. No siempre puede confiar en buscar un valor en la DISPLAYvariable, ya que podría establecerse con un valor no válido.

if xhost >& /dev/null ; then echo "Display exists"
else echo "Display invalid" ; fi

La razón por la que hago esto es porque ejecuto varios scripts en mi usuario crontabque operan en la pantalla cuando existe, pero funcionan de manera diferente cuando no. En la parte superior de mi crontab, configuré la DISPLAYvariable a :0pesar de que aún no existe. Las secuencias de comandos crontabque comienzan con @rebootcomenzarán independientemente de si tiene una pantalla o no. Esto le permitirá detectar dinámicamente cuándo su pantalla va y viene dentro del mismo script.

NOTA: El >&solo funciona en bash> = 4. De lo contrario, use> /dev/null 2>&1

cmevoli
fuente
Agradable, probado también con ssh -X; ¡funciona bien!
Alois Mahdal
13

Creo que verificar DISPLAYsería el mejor enfoque.

  • Maneja inicios de sesión remotos (por ejemplo, ssh -X).
  • Está disponible en la mayoría de las plataformas, si no en todas.
  • Es independiente del gestor de ventanas / DE.
Renan
fuente
2
También elegiría DISPLAY, o simplemente suprimiría el mensaje de error en general. Dale un /dev/nullpoco de amor de vez en cuando.
frostschutz
3
@frostschutz No, estoy tratando de ejecutar solo una parte relevante del script. La supresión de mensajes de error no da ningún paso en esa dirección. De hecho, puede conducir a una seria confusión al solucionar otros problemas que podrían romperse.
Alois Mahdal
1
Comencé a usar este enfoque poco después de la respuesta, y funcionó perfectamente con sshs simples hasta ahora, cuando comencé a hacer ssh -X--- para poder usar Vim sobre ssh para que el contenido seleccionado por modo visual llegue al portapapeles X local, para lo cual no necesita xserver en el lado del servidor. Por lo tanto, DISPLAY se configura como efecto de simplemente habilitar el reenvío, incluso si xserver y xset no están presentes.
Alois Mahdal
Eso sería entonces:if [[ $DISPLAY ]]; then … fi
Serge Stroobandt
1
Su DISPLAYvariable puede apuntar a una pantalla que en realidad no tiene un servidor X en ejecución (por ejemplo, cuando está codificado en un script, o el servidor X se cerró después de configurar la variable).
n
6

Usualmente uso la TERMvariable para probar X en mis scripts.

TERMusualmente está configurado linuxen TTY y xtermen X.
Uso la palabra "usualmente" aquí, ya que aplicaciones como GNU Screen y TMux parecen confundirse con la TERMVariable.

darnir
fuente
intente echo $TERMdescubrir la configuración de richt en su máquina en diferentes consolas. Yo uso [ $TERM == "linux" ] && echo do some stuffen Ubuntu
rubo77
3

Esto debería funcionar perfectamente bien:

[ ! -t 0 ] && xset b off                                  

http://tldp.org/LDP/abs/html/fto.html

-t

    file (descriptor) is associated with a terminal device

    This test option may be used to check whether the stdin [ -t 0 ] 
    or stdout [ -t 1 ] in a given script is a terminal.

Entonces, cuando esto se evalúa como falso ( [ ! -t 0 ]), estamos en un entorno GUI.

terdon
fuente
Con esto, obtengo el mismo resultado tanto en X como en la consola, es decir, [ -t 0 ]y [ -t 1 ]son ambos verdaderos.
Emanuel Berg
Extraño, funciona para mí cuando sshing en un host remoto.
terdon
[ -t 0 ]funciona bien en la consola en Ubuntu (usando CTRL ALT F1)
rubo77
0

Hay muchas formas de hacerlo.

En bash, intenta

function xruns {
    if [[ `pstree -As $$ | grep xinit | wc -l` == 1 ]]; then
        echo "You are in X."
    else
        echo "You are not in X."
    fi
}

O, en zsh, intente

#!/usr/bin/zsh

CURRENT_VT=`tty`

if [[ ${CURRENT_VT[6]} == "p" ]];        # or `${CURRENT_VT:5:1}` in bash
then
   # X stuff
else 
   # non-X stuff      
fi
Emanuel Berg
fuente
Punto tomado, pero ¿prueba su código antes de publicar? El primero tiene un error de sintaxis y no detecta realmente si estamos en una sesión X, por lo que lo hará echo 1si X se está ejecutando e inicia sesión a través de tty1-6 o ssh. El otro siempre hace "cosas que no son X". Creo que eso ${CURRENT_VT[6]}significa más bien la sexta línea que la sexta letra.
Alois Mahdal
@AloisMahdal: Ajá, mis cosas no funcionan en bash (uso zsh). No pensé en eso. Bueno, puede probarlo en zsh (tipo zsh) y posiblemente hacer algunas modificaciones si lo desea, para que funcione en bash.
Emanuel Berg
@AloisMahdal: OK, lo cambié. En cuanto al "iniciar sesión a través de tty1-6", como sucede, eso es lo que hago, y luego uso la segunda solución (arriba) y establezco una variable. Mira esto .zshrc y busca export VT. Utilizo la variable para contener en qué Linux VT / console / tty estoy (para el indicador zsh) pero en X, simplemente lo configuré en "X" (aunque no es un VT). Pero eso es detalles, podría resolverlo de la manera que desee en bash utilizando el mismo principio.
Emanuel Berg
He agregado la versión bash de la condición al segundo ejemplo. Sin embargo, creo que el primero todavía está mal. Tal vez tener ps imprimir solo antepasados ayudaría. Sin embargo, no estoy seguro de si es posible.
Alois Mahdal
@AloisMahdal: Mira la edición. Eso lo hace por mí, incluidas las cosas tty.
Emanuel Berg
0

if [[ $DISPLAY ]]

En la misma computadora, $DISPLAYvolverá , por ejemplo, 0:0en un emulador de terminal, pero nada en un terminal real. Esto se puede probar fácilmente con CtrlAltF1versus CtrlAltF7.

Una bashcondición basada en $DISPLAYse vería de la siguiente manera:

if [[ $DISPLAY ]]; then 
  
fi
Serge Stroobandt
fuente