¿Cómo detectar el entorno de escritorio en un script bash?

24

Estoy escribiendo un bashscript que necesita saber qué entorno de escritorio (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) se está ejecutando.

¿Cómo puedo obtener esa información?

Serge Stroobandt
fuente
1
eso es difícil porque incluso si está en una sesión de GNOME y acaba de iniciar un programa de KDE como kwrite, se ejecutará toda la infraestructura de KDE como KDE daemon y kdeinit.
Thorsten Staerk
3
Prácticamente no puedes, no de manera confiable. ¿Por qué necesitas saberlo? Esto parece un problema XY .
Gilles 'SO- deja de ser malvado'
@Gilles Buena pregunta. Estoy escribiendo un script especial para xplanety me gustaría actualizar automáticamente el fondo del escritorio con comandos específicos para el entorno de escritorio. Si desea publicar una respuesta a ese problema , siga el enlace.
Serge Stroobandt

Respuestas:

11

El principal problema con la comprobación DESKTOP_SESSIONes que lo configura el administrador de pantalla en lugar de la sesión de escritorio y está sujeto a inconsistencias. En lightdmDebian, los valores provienen de los nombres de los archivos debajo /usr/share/xsessions/. DESKTOP_SESSIONrefleja el entorno del escritorio si se realiza una selección específica al iniciar sesión, sin embargo, lightdm-xsessionsiempre se usa la sesión predeterminada.

GDMSESSIONes otra opción, pero parece tener una situación similar (es el mismo valor que DESKTOP_SESSIONpara mí).

XDG_CURRENT_DESKTOPparece una buena opción, sin embargo, actualmente no está en el estándar XDG y, por lo tanto, no siempre se implementa. Ver aquí para una discusión de esto. Esta respuesta muestra sus valores para diferentes distribuciones / escritorios, también puedo confirmar que actualmente no está disponible para mí en XFCE.

La alternativa razonable para XDG_CURRENT_DESKTOPno existir sería intentarlo XDG_DATA_DIRS. Siempre que los archivos de datos para el entorno de escritorio estén instalados en un directorio con su nombre, este enfoque debería funcionar. ¡Esperemos que este sea el caso para todas las distribuciones / escritorios!

Las siguientes pruebas (con GNU grep) para XFCE, KDE y Gnome:

echo "$XDG_DATA_DIRS" | grep -Eo 'xfce|kde|gnome'

POSIX compatible:

echo "$XDG_DATA_DIRS" | sed 's/.*\(xfce\|kde\|gnome\).*/\1/'

Para combinar con la comprobación XDG_CURRENT_DESKTOP:

if [ "$XDG_CURRENT_DESKTOP" = "" ]
then
  desktop=$(echo "$XDG_DATA_DIRS" | sed 's/.*\(xfce\|kde\|gnome\).*/\1/')
else
  desktop=$XDG_CURRENT_DESKTOP
fi

desktop=${desktop,,}  # convert to lower case
echo "$desktop"
Graeme
fuente
Me gusta esto. Según esta descripción general , solo habrá un problema con Cinnamon. Sin embargo, esto eventualmente podría resolverse abriendo un informe de error con Linux Mint.
Serge Stroobandt
@ on4aa MATE no está en la lista, es probable que tenga el mismo problema. apt-filetambién es una buena herramienta para ver dónde se instalan los distintos escritorios.
Graeme
1
Esta solución todavía se está inclinando fuertemente hacia distribuciones basadas en Debian. Ninguno de los métodos discutidos funciona en ninguna de las distribuciones basadas en Red Hat a las que tengo acceso (Fedora, CentOS, etc.).
slm
@slm interesante, ¿ XDG_DATA_DIRSno existe o simplemente no contiene nada útil?
Graeme
1
@slm muy cierto, creo que el OP probablemente sea mejor tratando de hacer lo que quiere hacer para cada escritorio con un ||estilo. Aún así, esta pregunta se ha hecho en otros sitios de SE, creo que tenemos el mejor conjunto de respuestas.
Graeme
10

Método # 1 - $ DESKTOP_SESSION

Creo que puedes averiguarlo interrogando la variable de entorno $DESKTOP_SESSION. No estoy del todo seguro de cuán ampliamente es compatible, pero en mis pruebas limitadas parece estar disponible en Fedora y Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Otra opción es la $XDG_SESSION_DESKTOPvariable.

Método # 2 - wmctrl

También existe este método que hace uso de wmctrl.

$ wmctrl  -m
Name: GNOME Shell
Class: N/A
PID: N/A
Window manager's "showing the desktop" mode: N/A

Referencias

slm
fuente
1
@ on4aa: $GDMSESSIONme pone nervioso, ya que es probable que solo esté orientado a DE que estén utilizando GDM o DE basado en GNOME. GDM = Administrador de pantalla de GNOME.
slm
1
@ on4aa DESKTOP_SESSIONen xfce.
Graeme
1
en xfce, mi DESKTOP_SESSION es default(mint 15)
glenn jackman
1
Debian también se mostró defaultpor esto. Una instalación predeterminada de GNOME 3.
slm
1
$DESKTOP_SESSIONmuestra defaultpara KDE bajo Fedora 20.
Matthew Cline
5

Puedes usar este script bash . Puede detectar el nombre y la versión del entorno de escritorio.

#!/bin/bash

function detect_gnome()
{
    ps -e | grep -E '^.* gnome-session$' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi
    VERSION=`gnome-session --version | awk '{print $2}'`
    DESKTOP="GNOME"
    return 1
}

function detect_kde()
{
    ps -e | grep -E '^.* kded4$' > /dev/null
    if [ $? -ne 0 ];
    then
        return 0
    else    
        VERSION=`kded4 --version | grep -m 1 'KDE' | awk -F ':' '{print $2}' | awk '{print $1}'`
        DESKTOP="KDE"
        return 1
    fi
}

function detect_unity()
{
    ps -e | grep -E 'unity-panel' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi
    VERSION=`unity --version | awk '{print $2}'`
    DESKTOP="UNITY"
    return 1
}

function detect_xfce()
{
    ps -e | grep -E '^.* xfce4-session$' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi
    VERSION=`xfce4-session --version | grep xfce4-session | awk '{print $2}'`
    DESKTOP="XFCE"
    return 1
}

function detect_cinnamon()
{
    ps -e | grep -E '^.* cinnamon$' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi
    VERSION=`cinnamon --version | awk '{print $2}'`
    DESKTOP="CINNAMON"
    return 1
}

function detect_mate()
{
    ps -e | grep -E '^.* mate-panel$' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi
    VERSION=`mate-about --version | awk '{print $4}'`
    DESKTOP="MATE"
    return 1
}

function detect_lxde()
{
    ps -e | grep -E '^.* lxsession$' > /dev/null
    if [ $? -ne 0 ];
    then
    return 0
    fi

    # We can detect LXDE version only thru package manager
    which apt-cache > /dev/null 2> /dev/null
    if [ $? -ne 0 ];
    then
    which yum > /dev/null 2> /dev/null
    if [ $? -ne 0 ];
    then
        VERSION='UNKNOWN'
    else
        # For Fedora
        VERSION=`yum list lxde-common | grep lxde-common | awk '{print $2}' | awk -F '-' '{print $1}'`
    fi
    else    
    # For Lubuntu and Knoppix
    VERSION=`apt-cache show lxde-common /| grep 'Version:' | awk '{print $2}' | awk -F '-' '{print $1}'`
    fi
    DESKTOP="LXDE"
    return 1
}

function detect_sugar()
{
    if [ "$DESKTOP_SESSION" == "sugar" ];
    then
    VERSION=`python -c "from jarabe import config; print config.version"`
    DESKTOP="SUGAR"
    else
    return 0
    fi
}


DESKTOP="UNKNOWN"
if detect_unity;
then
    if detect_kde;
    then
    if detect_gnome;
    then
        if detect_xfce;
        then
        if detect_cinnamon;
        then
            if detect_mate;
            then
            if detect_lxde;
            then
                detect_sugar
            fi
            fi
        fi
        fi
    fi
    fi
fi


if [ "$1" == '-v' ];
then
    echo $VERSION
else
    if [ "$1" == '-n' ];
    then
    echo $DESKTOP
    else
    echo $DESKTOP $VERSION
    fi
fi
alexeevdv
fuente
Funciona en Arch Linux
Colin Keenan
Robé tu idea para verificar solo Xfce en mi guión:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan
1
Esto no funcionó para mí en lo GNOME Shell 3.26.2que tengo UNKNOWN. No tengo ningún resultado que gnome-session --versionfuncione para mí, gnome-shell --version | awk '{print $3}'porque tampoco obtuve nada ps -e | grep -E '^.* gnome-session$'. Esto parece ser debido -bal final de gnome-session-b. Eliminando las $obras o simplemente ps -e | grep 'gnome-session'. Con estos cambios, el script está funcionando. TengoGNOME 3.26.2
nath
1

Eso probablemente depende de la situación. Si sabe qué administrador de pantalla se utiliza, puede ser que este coloque esta información en una variable de entorno.

Si ese no es el caso, entonces supongo que debe verificar cada DE que desea poder identificar. Todos ellos deben presentar sus propias variables de entorno.

Hauke ​​Laging
fuente
Me pregunto si echo ${DESKTOP_SESSION:0:1}haría el truco. Por lo que pude probar, regresa upara Unity y xpara XFCE. Esperemos que algunas personas intervengan para KDE y otros escritorios.
Serge Stroobandt
1
@ on4aa Es echo ${DESKTOP_SESSION} kde-plasma-safepara mi KDE. Whyever "safe" ...
Hauke ​​Laging
¿Hay algunos usuarios de Linux Mint Mate / Cinnamon aquí? E17, LXDE, etc. también son bienvenidos ...
Serge Stroobandt
1

Si la variable ambiental XDG_CURRENT_DESKTOPestá disponible, debería decírselo.

# echo $XDG_CURRENT_DESKTOP
KDE
Matthew Cline
fuente
1
No es una sorpresa, pero los demás saben que pasan por este Q&A: no existe en GNOME DE.
slm
De hecho, con énfasis en "si está disponible". Vea también esta respuesta de Askubuntu .
Serge Stroobandt
1

Podrías buscar Xorgprocesos en ejecución . El padre de esto debería ser su administrador de pantalla. Sus descendientes deben dar una indicación de qué entorno de escritorio se está ejecutando. En mi sistema, el administrador de visualización se ejecuta solo (con diferentes parámetros). Esto genera x-session-managerel enlace simbólico a xfce4-session. Esto puede ser suficiente, pero todos los elementos secundarios de esto están relacionados con mi entorno de escritorio. Encontrarlos a través del árbol de procesos debería ser la mejor manera de excluir elementos de otros sistemas de ventanas iniciados por varios programas (o quizás deliberadamente).

Mi primer pensamiento fue que sería mejor buscar el administrador de ventanas asociado con su entorno de escritorio, pero a menudo se puede configurar uno diferente para que se ejecute (por ejemplo, xmonaden Gnome), por lo que esto no es robusto. El mejor para buscar es probablemente el que administra el escritorio real, por ejemplo, xfdesktopo cualquier elemento del entorno de escritorio que realmente necesite para que su script funcione :)

Ejemplo

Aquí hay un ejemplo usando procps-ng ( -Cy --ppidno son POSIX). Se supone que es solo una instancia de Xorg.

Este es solo un ejemplo que funciona para el escritorio xfce. Un ejemplo de trabajo completo requiere una investigación de los procesos que utiliza cada sistema de escritorio, así como la mayoría de las otras soluciones requieren una investigación sobre cómo se establecen las variables ambientales en otros sistemas de escritorio.

X=Xorg

search_descendants ()
{
  ps h -o comm --ppid $1 |
    grep -E '^(xfdesktop|another_desktop_process)$' &&
    return 0

  for pid in $(ps h -o pid --ppid $1)
  do
    search_descendants $pid && return 0
  done

  return 1
}

dm_pid=$(ps h -o ppid -C "$X")

case "$(search_descendants $dm_pid)" in
  xfdesktop)
    desktop=xfce
    ;;
  another_desktop_process)
    desktop=another_desktop
    ;;
  *)
    desktop=unknown
    ;;
esac

echo $desktop
Graeme
fuente
Esto vuelve unknownen Ubuntu.
Serge Stroobandt
@ on4aa, eso no estaba destinado a ser una solución completa. Se suponía que este era un ejemplo que funciona para el escritorio xfce. Un ejemplo de trabajo completo requiere una investigación de los procesos que utiliza cada sistema de escritorio. Pensé que eso habría sido obvio al leer el código.
Graeme
@Greame Tienes razón; Fui demasiado rápido y pasé por alto el another_desktopresultado inacabado .
Serge Stroobandt
1

De todos los experimentos reportados en los numerosos comentarios, creo que es mi deber como OP dar una respuesta consensuada. (Tenga la seguridad de que me complacería revisar esta respuesta en caso de que haya datos contrastantes disponibles).

Por ahora, parece mejor tomar nuestra iniciativa $XDG_CURRENT_DESKTOPcuando se define esta variable. Si no, $XDG_DATA_DIRSpuede proporcionar la información deseada, más que la primera letra de ${DESKTOP_SESSION:0:1}.

Serge Stroobandt
fuente
Yo no tengo XDG_CURRENT_DESKTOP. Creo que el principal problema con estas variables es que las establece el administrador de pantalla en lugar del entorno de escritorio y, por lo tanto, hay cierta inconsistencia. Cuando elijo una sesión por defecto (Xfce) con LightDM echo $DESKTOP_SESSIONda lightdm-xsessionque es una amalgama de lightdmy x-session-manager, el proceso utilizado para iniciar mi escritorio (enlace simbólico a xfce4-session). Me imagino que instalar con una sesión predeterminada diferente solo usará un enlace simbólico diferente y producirá lo mismoDESKTOP_SESSION
Graeme
Notablemente, si elijo específicamente XFCE o Gnome del administrador de pantalla, en DESKTOP_SESSIONrealidad diré xfceognome
Graeme
1
Esta solución todavía se está inclinando fuertemente hacia distribuciones basadas en Debian. Ninguno de los métodos discutidos funciona en ninguna de las distribuciones basadas en Red Hat a las que tengo acceso (Fedora, CentOS, etc.).
slm
1

Esto funciona tanto en Ubuntu 18.10 (cósmico) [tipo lxqt] como en Mint 19 (tara) [tipo canela]:

$  set | grep XDG_CURRENT_DESKTOP | tr '[:upper:]' '[:lower:]' | cut -d'=' -f2

Capture el resultado en una variable y ejecute más código necesario a través de una lógica analítica capaz (caso, si / entonces) que incluye cualquiera / todos los tipos reconocidos desde allí; y / o funcionan correctamente cuando se usan tipos no reconocidos.

odoncaoa
fuente
Funciona también con Xubuntu LTS 18.04.
Serge Stroobandt