Comment détecter l'environnement de bureau dans un script bash?

24

J'écris un bashscript qui a besoin de savoir quel environnement de bureau (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) est en cours d'exécution.

Comment puis-je obtenir ces informations?

Serge Stroobandt
la source
1
c'est difficile car même si vous êtes dans une session GNOME et que vous venez de démarrer un programme KDE comme kwrite, toute l'infrastructure KDE comme le démon KDE et kdeinit sera en cours d'exécution.
Thorsten Staerk
3
Vous ne pouvez presque pas, pas de manière fiable. Pourquoi avez-vous besoin de savoir? Cela ressemble à un problème XY .
Gilles 'SO- arrête d'être méchant'
@Gilles Bonne question. J'écris un script spécialisé pour xplanetet je souhaite actualiser automatiquement l'arrière-plan du bureau avec des commandes spécifiques à l'environnement de bureau. Si vous souhaitez publier une réponse à ce problème , veuillez suivre le lien.
Serge Stroobandt

Réponses:

11

Le principal problème lié à la vérification du DESKTOP_SESSIONest qu'il est défini par le gestionnaire d'affichage plutôt que par la session de bureau et est sujet à des incohérences. Pour lightdmsur Debian, les valeurs proviennent des noms des fichiers sous /usr/share/xsessions/. DESKTOP_SESSIONreflète l'environnement du bureau si une sélection spécifique est effectuée lors de la connexion, mais la lightdm-xsessionsession par défaut est toujours utilisée.

GDMSESSIONest une autre option, mais semble avoir une situation similaire (c'est la même valeur que DESKTOP_SESSIONpour moi).

XDG_CURRENT_DESKTOPsemble être un bon choix, mais il n'est actuellement pas dans la norme XDG et donc pas toujours implémenté. Voir ici pour une discussion à ce sujet. Cette réponse montre ses valeurs pour différentes distributions / ordinateurs de bureau, je peux également confirmer qu'elle n'est actuellement pas disponible pour moi sur XFCE.

La solution de rechange raisonnable pour XDG_CURRENT_DESKTOPne pas exister serait d'essayer XDG_DATA_DIRS. À condition que les fichiers de données de l'environnement de bureau soient installés dans un répertoire portant son nom, cette approche devrait fonctionner. Espérons que ce sera le cas pour toutes les distributions / ordinateurs de bureau!

Les tests suivants (avec GNU grep) pour XFCE, KDE et Gnome:

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

Compatible POSIX:

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

À combiner avec la vérification 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
la source
J'aime ça. Selon cet aperçu , il n'y aura qu'un problème avec la cannelle. Cependant, cela pourrait éventuellement être résolu en ouvrant un rapport de bogue avec Linux Mint.
Serge Stroobandt
@ on4aa MATE n'est pas sur la liste, il est probable qu'il ait le même problème. apt-fileest également un bon outil pour voir où les différents bureaux s’installent.
Graeme
1
Cette solution penche toujours fortement vers les distributions basées sur Debian. Aucune des méthodes discutées ne fonctionne sur aucune des distributions basées sur Red Hat auxquelles j'ai accès (Fedora, CentOS, etc.).
slm
@slm intéressant, n'existe XDG_DATA_DIRSpas ou ne contient-il simplement rien d'utile?
Graeme
1
@slm très vrai, je pense que l'OP est probablement mieux d'essayer de faire ce qu'il veut faire pour chaque bureau dans un ||style. Pourtant, cette question a été posée sur d'autres sites SE, je pense que nous avons le meilleur ensemble de réponses.
Graeme
10

Méthode n ° 1 - $ DESKTOP_SESSION

Je pense que vous pouvez le découvrir en interrogeant la variable d'environnement $DESKTOP_SESSION. Je ne suis pas tout à fait sûr de la large prise en charge de cela, mais dans mes tests limités, il semble être disponible sur Fedora et Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Un autre choix est la $XDG_SESSION_DESKTOPvariable.

Méthode n ° 2 - wmctrl

Il y a aussi cette méthode qui utilise wmctrl.

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

Les références

slm
la source
1
@ on4aa - $GDMSESSIONme rend nerveux car il est probablement uniquement orienté vers DE qui utilisent GDM ou DE basé sur GNOME. GDM = Gestionnaire d'affichage GNOME.
slm
1
@ on4aa DESKTOP_SESSIONsur xfce.
Graeme
1
sur xfce, mon DESKTOP_SESSION est default(mint 15)
glenn jackman
1
Debian l'a montré defaultaussi. Une installation par défaut de GNOME 3.
slm
1
$DESKTOP_SESSIONmontre defaultpour KDE sous Fedora 20.
Matthew Cline
5

Vous pouvez utiliser ce script bash . Il peut détecter le nom et la version de l'environnement de bureau.

#!/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
la source
Fonctionne sur Arch Linux
Colin Keenan
J'ai volé votre idée de vérifier juste pour Xfce dans mon script:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan
1
cela ne fonctionne pas pour moi que GNOME Shell 3.26.2je suis arrivé UNKNOWN. Aucune sortie de gnome-session --versiontravail pour moi, c'est que gnome-shell --version | awk '{print $3}'je n'ai rien retiré non plus ps -e | grep -E '^.* gnome-session$'. Cela semble être dû -bà la fin de gnome-session-b. Suppression des $œuvres ou tout simplement ps -e | grep 'gnome-session'. Avec ces changements, le script fonctionne. Je reçoisGNOME 3.26.2
nath
1

Cela dépend probablement de la situation. Si vous savez quel gestionnaire d'affichage est utilisé, il se peut que celui-ci place ces informations dans une variable d'environnement.

Si ce n'est pas le cas, je suppose que vous devez vérifier chaque DE que vous souhaitez pouvoir identifier. Tous doivent introduire leurs propres variables d'environnement.

Hauke ​​Laging
la source
Je me demande si echo ${DESKTOP_SESSION:0:1}ça ferait l'affaire? Autant que j'ai pu tester, il revient upour Unity et xpour XFCE. Avec un peu de chance, certaines personnes joueront le rôle de KDE et d'autres ordinateurs de bureau.
Serge Stroobandt
1
@ on4aa C'est echo ${DESKTOP_SESSION} kde-plasma-safepour mon KDE. Pourquoi "sûr" ...
Hauke ​​Laging
Y a-t-il des utilisateurs Linux Mint Mate / Cinnamon ici? E17, LXDE, etc. sont également les bienvenus ...
Serge Stroobandt
1

Si la variable d'environnement XDG_CURRENT_DESKTOPest disponible, elle devrait vous le dire.

# echo $XDG_CURRENT_DESKTOP
KDE
Matthew Cline
la source
1
Pas une surprise mais juste pour que les autres sachent que passer par ce Q&A: n'existe pas dans GNOME DE.
slm
En effet, en mettant l'accent sur "si disponible". Voir aussi cette réponse Askubuntu .
Serge Stroobandt le
1

Vous pouvez rechercher des Xorgprocessus en cours d'exécution . Le parent de ceci devrait être votre gestionnaire d'affichage. Ses descendants devraient donner une indication de l'environnement de bureau en cours d'exécution. Sur mon système, le gestionnaire d'affichage s'exécute lui-même (avec différents paramètres). Cela se produit alors x-session-managerqui est lié à xfce4-session. Cela peut être suffisant, mais tous les enfants sont liés à mon environnement de bureau. Les trouver via l'arborescence des processus devrait être le meilleur moyen d'exclure des éléments d'autres systèmes de fenêtres démarrés par divers programmes (ou peut-être délibérément).

Ma première pensée a été qu'il serait préférable de rechercher le gestionnaire de fenêtres associé à votre environnement de bureau, mais souvent un autre peut être configuré pour s'exécuter (par exemple xmonaddans Gnome) donc ce n'est pas robuste. Le meilleur à rechercher est probablement celui qui gère le bureau réel, par exemple xfdesktopou tout autre élément de l'environnement de bureau dont vous avez réellement besoin pour que votre script fonctionne :)

Exemple

Voici un exemple utilisant procps-ng ( -Cet --ppidne sont pas POSIX). Il suppose que le est une seule instance de Xorg.

Ceci est juste un exemple qui fonctionne pour le bureau xfce. Un exemple de travail complet nécessite une enquête sur les processus utilisés par chaque système de bureau, tout comme la plupart des autres solutions nécessitent une enquête sur la façon dont les variables d'environnement sont définies dans divers autres systèmes de bureau.

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
la source
Cela revient unknownsur Ubuntu.
Serge Stroobandt
@ on4aa, ce n'était pas censé être une solution complète. C'était censé être un exemple qui fonctionne pour le bureau xfce. Un exemple de travail complet nécessite une enquête sur les processus utilisés par chaque système de bureau. J'ai pensé que cela aurait été évident à la lecture du code.
Graeme
@Greame Vous avez raison; J'ai été un peu trop rapide et j'ai ignoré le another_desktoprésultat inachevé .
Serge Stroobandt le
1

De toutes les expériences rapportées dans les nombreux commentaires, je pense que c'est mon devoir en tant que PO de trouver une réponse consensuelle. (Rassurez-vous, je serais heureux de revoir cette réponse si des données contrastées devenaient disponibles.)

Pour l'instant, il semble préférable de prendre les devants à partir du $XDG_CURRENT_DESKTOPmoment où cette variable est définie. Sinon, $XDG_DATA_DIRSpeut fournir les informations souhaitées, plus que la première lettre de ${DESKTOP_SESSION:0:1}.

Serge Stroobandt
la source
Je n'en ai pas XDG_CURRENT_DESKTOP. Je pense que le principal problème avec ces variables est qu'elles sont définies par le gestionnaire d'affichage plutôt que par l'environnement de bureau et qu'il y a donc une certaine incohérence. Lorsque je choisis une session par défaut (xfce) avec lightdm echo $DESKTOP_SESSIONdonne lightdm-xsessionqui est une fusion de lightdmet x-session-manager, le processus utilisé pour démarrer mon bureau (lien symbolique vers xfce4-session). J'imagine que l'installation avec une session par défaut différente utilisera simplement un lien symbolique différent et donnera le mêmeDESKTOP_SESSION
Graeme
Notamment, si je choisis spécifiquement XFCE ou Gnome dans le gestionnaire d'affichage, DESKTOP_SESSIONdira en fait xfceougnome
Graeme
1
Cette solution penche toujours fortement vers les distributions basées sur Debian. Aucune des méthodes discutées ne fonctionne sur aucune des distributions basées sur Red Hat auxquelles j'ai accès (Fedora, CentOS, etc.).
slm
1

Cela fonctionne sur Ubuntu 18.10 (cosmique) [type lxqt] et Mint 19 (tara) [type cannelle]:

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

Capturez le résultat dans une variable et exécutez le code supplémentaire nécessaire via une logique analytique capable (cas stmt, si / alors) qui inclut tous les types reconnus à partir de là; et / ou fonctionnent correctement lorsque des types non reconnus sont utilisés.

odoncaoa
la source
Fonctionne également avec Xubuntu LTS 18.04.
Serge Stroobandt