Come rilevare l'ambiente desktop in uno script bash?


24

Sto scrivendo uno bashscript che deve sapere quale ambiente desktop (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) è in esecuzione.

Come posso ottenere tali informazioni?


1
è difficile perché anche se sei in una sessione GNOME e hai appena avviato un programma KDE come kwrite, saranno in esecuzione tutte le infrastrutture di KDE come il demone KDE e kdeinit.
Thorsten Staerk,

3
Praticamente non puoi, non in modo affidabile. Perché hai bisogno di sapere? Sembra un problema XY .
Gilles 'SO- smetti di essere malvagio' il

@Gilles Buona domanda. Sto scrivendo uno script speciale per xplanete vorrei aggiornare automaticamente lo sfondo del desktop con comandi specifici per l'ambiente desktop. Se ti piace pubblicare una risposta a quel problema , segui il link.
Serge Stroobandt,

Risposte:


11

Il problema principale con il controllo DESKTOP_SESSIONè che è impostato dal display manager piuttosto che dalla sessione desktop ed è soggetto a incongruenze. Per lightdmDebian, i valori provengono dai nomi dei file in /usr/share/xsessions/. DESKTOP_SESSIONriflette l'ambiente desktop se viene effettuata una selezione specifica all'accesso, tuttavia lightdm-xsessionviene sempre utilizzata la sessione predefinita.

GDMSESSIONè un'altra opzione, ma sembra avere una situazione simile (è lo stesso valore DESKTOP_SESSIONper me).

XDG_CURRENT_DESKTOPsembra una buona scelta, tuttavia non è attualmente nello standard XDG e quindi non sempre implementato. Vedi qui per una discussione di questo. Questa risposta mostra i suoi valori per diverse distro / desktop, posso anche confermare che al momento non è disponibile per me su XFCE.

Il fallback ragionevole per XDG_CURRENT_DESKTOPnon esistere sarebbe provare XDG_DATA_DIRS. Se i file di dati per l'ambiente desktop sono installati in una directory che porta il suo nome, questo approccio dovrebbe funzionare. Speriamo che questo sia il caso di tutte le distro / desktop!

I seguenti test (con GNU grep) per XFCE, KDE e Gnome:

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

POSIX compatibile:

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

Da combinare con il controllo 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"

Mi piace questo. Secondo questa panoramica , ci sarà solo un problema con Cannella. Tuttavia, questo potrebbe eventualmente essere risolto aprendo una segnalazione di bug con Linux Mint.
Serge Stroobandt,

@ on4aa MATE non è nell'elenco, è probabile che abbia lo stesso problema. apt-fileè anche un buon strumento per vedere dove si installano i vari desktop.
Graeme,

1
Questa soluzione è ancora fortemente orientata verso le distribuzioni basate su Debian. Nessuno dei metodi discussi funziona su nessuna delle distro basate su Red Hat a cui ho accesso (Fedora, CentOS, ecc.).
slm

@slm interessante, XDG_DATA_DIRSnon esiste o semplicemente non contiene nulla di utile?
Graeme,

1
@slm molto vero, penso che l'OP sia probabilmente meglio cercare di fare quello che vuole fare per ogni desktop in uno ||stile. Tuttavia questa domanda è stata posta su altri siti SE, penso che abbiamo la migliore serie di risposte.
Graeme,

10

Metodo n. 1 - $ DESKTOP_SESSION

Penso che puoi scoprirlo interrogando la variabile d'ambiente $DESKTOP_SESSION. Non sono del tutto sicuro di quanto ampiamente sia supportato, ma nei miei test limitati sembra essere disponibile su Fedora e Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Un'altra scelta è la $XDG_SESSION_DESKTOPvariabile.

Metodo n. 2 - wmctrl

C'è anche questo metodo che fa uso di wmctrl.

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

Riferimenti


1
@ on4aa - $GDMSESSIONmi rende nervoso poiché probabilmente è orientato solo verso DE che utilizzano GDM o DE basato su GNOME. GDM = GNOME Display Manager.
slm

1
@ on4aa DESKTOP_SESSIONsu xfce.
Graeme,

1
su xfce, il mio DESKTOP_SESSION è default(nuovo 15)
Glenn Jackman,

1
Debian ha mostrato anche defaultper questo. Un'installazione predefinita di GNOME 3.
slm

1
$DESKTOP_SESSIONmostra defaultper KDE sotto Fedora 20.
Matthew Cline,

5

Puoi usare questo script bash . Può rilevare il nome e la versione dell'ambiente desktop.

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

Funziona su Arch Linux
Colin Keenan il

Ho rubato la tua idea di controllare solo Xfce nella mia sceneggiatura:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan,

1
questo non ha funzionato per me su GNOME Shell 3.26.2ho ottenuto UNKNOWN. Nessun risultato dal gnome-session --versionmio lavoro è gnome-shell --version | awk '{print $3}'che non ho ottenuto nulla da ps -e | grep -E '^.* gnome-session$'. Questo sembra essere dovuto -balla fine di gnome-session-b. Rimozione delle $opere o semplicemente ps -e | grep 'gnome-session'. Con queste modifiche lo script funziona. RicevoGNOME 3.26.2
Nath il

1

Ciò dipende probabilmente dalla situazione. Se sai quale display manager viene utilizzato, è possibile che questo inserisca queste informazioni in una variabile di ambiente.

In caso contrario, suppongo che si debba verificare ogni DE che si desidera poter identificare. Tutti dovrebbero introdurre le proprie variabili d'ambiente.


Mi chiedo se echo ${DESKTOP_SESSION:0:1}farebbe il trucco? Per quanto ho potuto provare, ritorna uper Unity e xper XFCE. Spero che alcune persone suonino per KDE e altri desktop.
Serge Stroobandt,

1
@ on4aa È echo ${DESKTOP_SESSION} kde-plasma-safeper il mio KDE. Whyever "safe" ...
Hauke ​​Laging,

Ci sono alcuni utenti Linux Mint Mate / Cinnamon qui? Anche E17, LXDE, ecc. Sono i benvenuti ...
Serge Stroobandt,

1

Se la variabile ambientale XDG_CURRENT_DESKTOPè disponibile, dovrebbe dirlo.

# echo $XDG_CURRENT_DESKTOP
KDE

1
Non è una sorpresa, ma solo così gli altri sono consapevoli che passano queste domande e risposte: non esiste in GNOME DE.
slm

Anzi, con enfasi su "se disponibile". Vedi anche questa risposta Askubuntu .
Serge Stroobandt,

1

Potresti cercare Xorgprocessi in esecuzione . Il genitore di questo dovrebbe essere il tuo display manager. I suoi discendenti dovrebbero dare un'indicazione di quale ambiente desktop è in esecuzione. Sul mio sistema, il display manager si esegue da solo (con parametri diversi). Questo allora depone le uova x-session-manager, che è collegato simbolicamente a xfce4-session. Questo può essere sufficiente, ma tutti i figli di questo sono legati al mio ambiente desktop. Trovarli tramite l'albero dei processi dovrebbe essere il modo migliore per escludere elementi di altri sistemi di finestre avviati da vari programmi (o forse deliberatamente).

Il mio primo pensiero è stato che sarebbe meglio cercare il gestore di finestre associato al proprio ambiente desktop, ma spesso è possibile configurarne uno diverso per l'esecuzione (ad esempio xmonadin Gnome), quindi non è affidabile. Il migliore da cercare è probabilmente quello che gestisce il desktop reale, ad esempio xfdesktopo qualsiasi elemento dell'ambiente desktop di cui hai effettivamente bisogno per far funzionare il tuo script :)

Esempio

Ecco un esempio usando procps-ng ( -Ce --ppidnon sono POSIX). Presuppone che sia solo un'istanza di Xorg.

Questo è solo un esempio che funziona per il desktop xfce. Un esempio di lavoro completo richiede un'indagine sui processi utilizzati da ciascun sistema desktop, così come la maggior parte delle altre soluzioni richiede un'indagine su come le variabili ambientali sono impostate in vari altri sistemi desktop.

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

Questo ritorna unknownsu Ubuntu.
Serge Stroobandt,

@ on4aa, quella non doveva essere una soluzione completa. Questo doveva essere un esempio che funziona per il desktop xfce. Un esempio di funzionamento completo richiede un'indagine sui processi utilizzati da ciascun sistema desktop. Ho pensato che sarebbe stato ovvio dalla lettura del codice.
Graeme,

@Greame Hai ragione; Ero un po 'troppo veloce e ho trascurato il another_desktoprisultato incompiuto .
Serge Stroobandt,

1

Da tutti gli esperimenti riportati nei numerosi commenti, penso che sia mio dovere come PO presentare una risposta di consenso. (State tranquilli, sarei felice di rivedere questa risposta se fossero disponibili dati contrastanti.)

Per ora, sembra meglio prendere il nostro esempio da $XDG_CURRENT_DESKTOPquando viene definita questa variabile. In caso contrario, $XDG_DATA_DIRSpuò fornire le informazioni desiderate, più della prima lettera di ${DESKTOP_SESSION:0:1}.


Io non ho XDG_CURRENT_DESKTOP. Penso che il problema principale con queste siano le variabili in quanto sono impostate dal display manager piuttosto che dall'ambiente desktop e quindi c'è qualche incoerenza. Quando scelgo una sessione predefinita (xfce) con lightdm echo $DESKTOP_SESSIONlightdm-xsessionquale è una fusione di lightdme x-session-manager, il processo usato per avviare il mio desktop (collegato a xfce4-session). Immagino che l'installazione con una diversa sessione predefinita userà semplicemente un link simbolico diverso e produrrà lo stessoDESKTOP_SESSION
Graeme,

In particolare, se scelgo specificamente XFCE o Gnome dal display manager, DESKTOP_SESSIONin realtà dirò xfceognome
Graeme

1
Questa soluzione è ancora fortemente orientata verso le distribuzioni basate su Debian. Nessuno dei metodi discussi funziona su nessuna delle distro basate su Red Hat a cui ho accesso (Fedora, CentOS, ecc.).
slm

1

Funziona su Ubuntu 18.10 (cosmico) [tipo lxqt] e Mint 19 (tara) [tipo cannella]:

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

Cattura il risultato in una variabile ed esegui ulteriore codice necessario attraverso una logica analitica capace (case stmt, if / then) che include qualsiasi / tutti i tipi riconosciuti da lì; e / o funzionano con grazia quando sono in uso tipi non riconosciuti.


Funziona anche con Xubuntu LTS 18.04.
Serge Stroobandt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.