Wie erkenne ich die Desktop-Umgebung in einem Bash-Skript?

24

Ich schreibe ein bashSkript, das wissen muss, welche Desktop-Umgebung (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) ausgeführt wird.

Wie kann ich diese Informationen erhalten?

Serge Stroobandt
quelle
1
Das ist schwierig, denn selbst wenn Sie sich in einer GNOME-Sitzung befinden und nur ein KDE-Programm wie kwrite gestartet haben, wird die gesamte KDE-Infrastruktur wie KDE-Daemon und kdeinit ausgeführt.
Thorsten Staerk
3
Sie können so ziemlich nicht, nicht zuverlässig. Warum willst du das wissen? Das sieht nach einem XY-Problem aus .
Gilles 'SO- hör auf böse zu sein'
@ Gilles Gute Frage. Ich schreibe ein Spezialskript für xplanetund möchte den Desktop-Hintergrund automatisch mit Befehlen aktualisieren, die für die Desktop-Umgebung spezifisch sind. Wenn Sie eine Antwort auf dieses Problem veröffentlichen möchten, folgen Sie bitte dem Link.
Serge Stroobandt

Antworten:

11

Das Hauptproblem bei der Überprüfung von DESKTOP_SESSIONist, dass es vom Anzeigemanager und nicht von der Desktopsitzung festgelegt wird und Inkonsistenzen unterliegt. Bei lightdmDebian stammen die Werte aus den Namen der Dateien unter /usr/share/xsessions/. DESKTOP_SESSIONspiegelt die Desktop-Umgebung wider, wenn beim Anmelden eine bestimmte Auswahl getroffen wird, es wird jedoch lightdm-xsessionimmer die Standard-Sitzung verwendet.

GDMSESSIONist eine andere Option, scheint aber eine ähnliche Situation zu haben (es ist der gleiche Wert wie DESKTOP_SESSIONfür mich).

XDG_CURRENT_DESKTOPsieht nach einer guten Wahl aus, ist aber derzeit nicht im XDG-Standard und daher nicht immer implementiert. Sehen Sie hier für eine Diskussion über diese. In dieser Antwort werden die Werte für verschiedene Distributionen / Desktops angezeigt. Ich kann auch bestätigen, dass sie für mich derzeit auf XFCE nicht verfügbar sind.

Der vernünftige Fallback für XDG_CURRENT_DESKTOPnicht existierende wäre, es zu versuchen XDG_DATA_DIRS. Vorausgesetzt, die Datendateien für die Desktop-Umgebung werden in einem Verzeichnis mit diesem Namen installiert, sollte dieser Ansatz funktionieren. Dies gilt hoffentlich für alle Distributionen / Desktops!

Die folgenden (mit GNU grep) Tests für XFCE, KDE und Gnome:

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

POSIX-kompatibel:

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

Mit dem Prüfen kombinieren 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
quelle
Ich mag das. Nach dieser Übersicht wird es nur ein Problem mit Zimt geben. Dies kann jedoch möglicherweise behoben werden, indem ein Fehlerbericht mit Linux Mint geöffnet wird.
Serge Stroobandt
@ on4aa MATE ist nicht auf der Liste, es ist wahrscheinlich dasselbe Problem. apt-fileist auch ein gutes Werkzeug, um zu sehen, wo die verschiedenen Desktops installiert werden.
Graeme
1
Diese Lösung neigt immer noch stark zu Debian-basierten Distributionen. Keine der besprochenen Methoden funktioniert auf allen Red Hat-basierten Distributionen, auf die ich Zugriff habe (Fedora, CentOS usw.).
SLM
@slm interessant, XDG_DATA_DIRSexistiert nicht oder enthält es einfach nichts nützliches?
Graeme
1
@slm sehr wahr, ich denke, das OP ist wahrscheinlich besser zu versuchen, das zu tun, was er für jeden Desktop in einem ||Stil tun möchte . Trotzdem wurde diese Frage auf anderen SE-Sites gestellt. Ich denke, wir haben die besten Antworten.
Graeme
10

Methode 1 - $ DESKTOP_SESSION

Ich denke, Sie können es herausfinden, indem Sie die Umgebungsvariable abfragen $DESKTOP_SESSION. Ich bin nicht ganz sicher, wie weit verbreitet dies ist, aber in meinen begrenzten Tests scheint es auf Fedora & Ubuntu verfügbar zu sein.

$ echo $DESKTOP_SESSION
gnome

Eine andere Wahl ist die $XDG_SESSION_DESKTOPVariable.

Methode 2 - wmctrl

Es gibt auch diese Methode, die davon Gebrauch macht wmctrl.

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

Verweise

slm
quelle
1
@ on4aa - $GDMSESSIONmacht mich nervös, da es wahrscheinlich nur auf DE ausgerichtet ist, die entweder GDM oder GNOME-basiertes DE verwenden. GDM = GNOME Display Manager.
slm
1
@ on4aa DESKTOP_SESSIONauf xfce.
Graeme
1
auf xfce ist meine DESKTOP_SESSION default(Mint 15)
Glenn Jackman
1
Debian zeigte defaultdies auch. Eine Standardinstallation von GNOME 3.
slm
1
$DESKTOP_SESSIONzeigt defaultfür KDE unter Fedora 20.
Matthew Cline
5

Sie können dieses Bash-Skript verwenden . Es kann den Namen und die Version der Desktop-Umgebung erkennen.

#!/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
quelle
Funktioniert auf Arch Linux
Colin Keenan
Ich habe deine Idee gestohlen, in meinem Skript nur nach Xfce zu suchen: ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan
1
das hat bei mir nicht geklappt auf den GNOME Shell 3.26.2ich gekommen bin UNKNOWN. Keine Ausgabe von gnome-session --versionArbeiten für mich ist, gnome-shell --version | awk '{print $3}'ich habe auch nichts raus bekommen ps -e | grep -E '^.* gnome-session$'. Dies scheint -bam Ende von zu liegen gnome-session-b. Entferne den$ Werke oder einfach nur ps -e | grep 'gnome-session'. Mit diesen Änderungen arbeitet das Skript. Ich bekommeGNOME 3.26.2
nath
1

Das hängt wahrscheinlich von der Situation ab. Wenn Sie wissen, welcher Anzeigemanager verwendet wird, kann es sein, dass dieser diese Informationen in eine Umgebungsvariable einfügt.

Wenn dies nicht der Fall ist, müssen Sie vermutlich nach jedem DE suchen, das Sie identifizieren möchten. Alle sollten ihre eigenen Umgebungsvariablen einführen.

Hauke ​​Laging
quelle
Ich frage mich, ob echo ${DESKTOP_SESSION:0:1}ich den Trick machen würde. Soweit ich testen konnte, kehrt es ufür Unity und xfür XFCE zurück. Hoffentlich werden einige Leute KDE und andere Desktops suchen.
Serge Stroobandt
1
@ on4aa Es ist echo ${DESKTOP_SESSION} kde-plasma-safefür mein KDE. Warum "sicher" ...
Hauke ​​Laging
Gibt es hier einige Linux Mint Mate / Cinnamon-Benutzer? E17, LXDE, etc. sind auch willkommen ...
Serge Stroobandt
1

Wenn die Umgebungsvariable XDG_CURRENT_DESKTOPverfügbar ist, sollte sie Ihnen mitteilen.

# echo $XDG_CURRENT_DESKTOP
KDE
Matthew Cline
quelle
1
Keine Überraschung, aber nur damit andere wissen, dass diese Frage & Antwort nicht in GNOME DE enthalten ist.
slm
In der Tat mit Schwerpunkt auf "sofern verfügbar". Siehe auch diese Askubuntu-Antwort .
Serge Stroobandt
1

Du könntest nach Laufen suchen Xorg Prozessen . Das übergeordnete Element sollte Ihr Display-Manager sein. Seine Nachkommen sollten einen Hinweis darauf geben, welche Desktop-Umgebung ausgeführt wird. Auf meinem System führt sich der Anzeigemanager selbst aus (mit verschiedenen Parametern). Dies wird dann erzeugt, x-session-managerwas mit symbolisch verbunden ist xfce4-session. Dies mag ausreichen, aber alle Kinder davon hängen mit meiner Desktop-Umgebung zusammen. Das Auffinden über den Prozessbaum sollte der beste Weg sein, Elemente anderer Fenstersysteme auszuschließen, die von verschiedenen Programmen (oder möglicherweise absichtlich) gestartet wurden.

Mein erster Gedanke war, dass es am besten ist, nach dem Fenstermanager zu suchen, der Ihrer Desktop-Umgebung zugeordnet ist. Oft kann jedoch auch ein anderer für die Ausführung konfiguriert werden (z. B. xmonad in Gnome), sodass dies nicht robust ist. Das Beste, wonach Sie suchen, ist wahrscheinlich das, das den eigentlichen Desktop verwaltet, z. B. xfdesktopoder welches Element der Desktop-Umgebung Sie tatsächlich benötigen, damit Ihr Skript funktioniert :)

Beispiel

Hier ist ein Beispiel für die Verwendung von procps-ng ( -Cund --ppidnicht POSIX). Es wird davon ausgegangen, dass dies nur eine Instanz von ist Xorg.

Dies ist nur ein Beispiel, das für den xfce-Desktop funktioniert. Ein vollständiges Arbeitsbeispiel erfordert eine Untersuchung der Prozesse, die von jedem Desktopsystem verwendet werden, ebenso wie die meisten anderen Lösungen eine Untersuchung darüber erfordern, wie Umgebungsvariablen in verschiedenen anderen Desktopsystemen festgelegt werden.

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
quelle
Dies kehrt unknownauf Ubuntu zurück.
Serge Stroobandt
@on4aa, das sollte keine Komplettlösung sein. Dies sollte ein Beispiel sein, das für den xfce-Desktop funktioniert. Ein vollständiges Beispiel erfordert eine Untersuchung der Prozesse, die von jedem Desktopsystem verwendet werden. Ich dachte, das wäre offensichtlich gewesen, wenn ich den Code gelesen hätte .
Graeme
@Greame Du hast recht; Ich war etwas zu schnell und habe das unvollendete another_desktopErgebnis übersehen .
Serge Stroobandt
1

Aus all den Experimenten, über die in den zahlreichen Kommentaren berichtet wurde, halte ich es für meine Pflicht als OP, eine Konsensantwort zu finden. (Seien Sie versichert, ich würde mich freuen, diese Antwort zu lesen, falls kontrastierende Daten verfügbar werden.)

Im Moment scheint es am besten zu sein, unseren Vorsprung $XDG_CURRENT_DESKTOPbei der Definition dieser Variablen zu übernehmen . Wenn nicht, $XDG_DATA_DIRSkann die gewünschte Information mehr als der erste Buchstabe von ${DESKTOP_SESSION:0:1}.

Serge Stroobandt
quelle
Ich habe keine XDG_CURRENT_DESKTOP. Ich denke, dass das Hauptproblem bei diesen Variablen darin besteht, dass sie vom Anzeigemanager und nicht von der Desktop-Umgebung festgelegt werden und es daher einige Inkonsistenzen gibt. Wenn ich eine Standardsitzung (Xfce) mit lightdm wählen echo $DESKTOP_SESSIONgibt , lightdm-xsessiondas ist ein Zusammenschluss von lightdmund den x-session-managerverwendeten Verfahren meines Desktop starten (Symlink zu xfce4-session). Ich stelle mir vor, dass bei der Installation mit einer anderen Standardsitzung nur ein anderer Symlink verwendet wird und dasselbe DESKTOP_SESSION
Ergebnis
Insbesondere, wenn ich XFCE oder Gnome aus dem Display-Manager auswähle, DESKTOP_SESSIONwird tatsächlich xfceodergnome
Graeme
1
Diese Lösung neigt immer noch stark zu Debian-basierten Distributionen. Keine der besprochenen Methoden funktioniert auf allen Red Hat-basierten Distributionen, auf die ich Zugriff habe (Fedora, CentOS usw.).
SLM
1

Dies funktioniert sowohl auf Ubuntu 18.10 (Cosmic) [lxqt type] als auch auf Mint 19 (Tara) [Cinnamon type]:

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

Erfassen Sie das Ergebnis in einer Variablen und führen Sie den weiteren erforderlichen Code über eine fähige analytische Logik (case stmt, if / then) aus, die alle von dort erkannten Typen enthält. und / oder ordnungsgemäß funktionieren, wenn nicht erkannte Typen verwendet werden.

odoncaoa
quelle
Funktioniert auch mit Xubuntu LTS 18.04.
Serge Stroobandt