Jak wykryć środowisko pulpitu w skrypcie bash?


24

Piszę bashskrypt, który musi wiedzieć, które środowisko pulpitu (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) jest uruchomione.

Jak mogę uzyskać te informacje?


1
jest to trudne, ponieważ nawet jeśli jesteś w sesji GNOME i właśnie uruchomiłeś jeden program KDE, taki jak kwrite, cała infrastruktura KDE, taka jak demon KDE i kdeinit, będzie działać.
Thorsten Staerk

3
Prawie nie możesz, niezawodnie. Po co ci to wiedzieć? To wygląda na problem XY .
Gilles „SO- przestań być zły”

@Gilles Dobre pytanie. Piszę specjalny skrypt xplaneti chciałbym automatycznie odświeżyć tło pulpitu za pomocą poleceń specyficznych dla środowiska pulpitu. Jeśli chcesz opublikować odpowiedź na ten problem , kliknij link.
Serge Stroobandt

Odpowiedzi:


11

Główny problem ze sprawdzaniem DESKTOP_SESSIONpolega na tym, że jest on ustawiany przez menedżera wyświetlania, a nie sesję pulpitu, i jest niespójny. W lightdmDebianie wartości pochodzą od nazw plików pod /usr/share/xsessions/. DESKTOP_SESSIONodzwierciedla środowisko pulpitu, jeśli podczas logowania dokonany zostanie określony wybór, jednak lightdm-xsessionzawsze używana jest sesja domyślna.

GDMSESSIONjest kolejną opcją, ale wydaje się mieć podobne położenie (to ta sama wartość, co DESKTOP_SESSIONdla mnie).

XDG_CURRENT_DESKTOPwygląda na dobry wybór, jednak obecnie nie jest on w standardzie XDG i dlatego nie zawsze jest implementowany. Zobacz tutaj do dyskusji o tym. Ta odpowiedź pokazuje jego wartości dla różnych dystrybucji / komputerów stacjonarnych, mogę również potwierdzić, że obecnie nie jest dla mnie dostępna w XFCE.

Uzasadnionym rozwiązaniem XDG_CURRENT_DESKTOPnieistniejącym byłoby spróbowanie XDG_DATA_DIRS. Pod warunkiem, że pliki danych dla środowiska pulpitu są zainstalowane w katalogu z jego nazwą, to podejście powinno działać. Miejmy nadzieję, że tak będzie w przypadku wszystkich dystrybucji / komputerów stacjonarnych!

Następujące (z GNU grep) testy dla XFCE, KDE i Gnome:

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

Kompatybilny z POSIX:

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

Aby połączyć z sprawdzaniem 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"

Lubię to. Według tego przeglądu będzie tylko problem z cynamonem. Jednak można to ostatecznie rozwiązać, otwierając raport o błędach w Linux Mint.
Serge Stroobandt

@ on4aa MATE nie ma na liście, prawdopodobnie ma ten sam problem. apt-filejest również dobrym narzędziem do sprawdzenia, gdzie instalują się różne komputery stacjonarne.
Graeme

1
To rozwiązanie nadal mocno opiera się na dystrybucjach opartych na Debianie. Żadna z omawianych metod nie działa na żadnej dystrybucji opartej na Red Hacie, do której mam dostęp (Fedora, CentOS itp.).
slm

@slm ciekawe, XDG_DATA_DIRSnie istnieje lub po prostu nie zawiera nic przydatnego?
Graeme

1
@slm bardzo prawda, myślę, że OP prawdopodobnie lepiej próbuje zrobić to, co chce dla każdego pulpitu w dobrym ||stylu. Nadal to pytanie zostało zadane na innych stronach SE, myślę, że mamy najlepszy zestaw odpowiedzi.
Graeme

10

Metoda nr 1 - $ DESKTOP_SESSION

Myślę, że można to sprawdzić, sprawdzając zmienną środowiskową $DESKTOP_SESSION. Nie jestem do końca przekonany, jak szeroko jest to obsługiwane, ale w moich ograniczonych testach wydaje się, że jest dostępny na Fedorze i Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Innym wyborem jest $XDG_SESSION_DESKTOPzmienna.

Metoda nr 2 - wmctrl

Istnieje również ta metoda, która wykorzystuje wmctrl.

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

Referencje


1
@ on4aa - $GDMSESSIONdenerwuje mnie, ponieważ prawdopodobnie jest nastawiony tylko na DE, które używają DE opartego na GDM lub GNOME. GDM = Menedżer wyświetlania GNOME.
slm

1
@ on4aa DESKTOP_SESSIONna Xfce .
Graeme

1
na Xfce, mój DESKTOP_SESSION to default(mint 15)
glenn jackman

1
Debian też to pokazał default. Domyślna instalacja GNOME 3.
slm

1
$DESKTOP_SESSIONpokazuje defaultdla KDE pod Fedorą 20.
Matthew Cline

5

Możesz użyć tego skryptu bash . Może wykryć nazwę i wersję środowiska pulpitu.

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

Działa na Arch Linux
Colin Keenan

Ukradłem twój pomysł, by sprawdzić tylko Xfce w moim skrypcie:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan

1
to nie działa dla mnie na GNOME Shell 3.26.2dostałam UNKNOWN. Nie mam wyjścia z gnome-session --versionpracy dla mnie, to gnome-shell --version | awk '{print $3}'też nie wyciągnąłem niczego ps -e | grep -E '^.* gnome-session$'. Wydaje się, że dzieje się tak z powodu -bkońca gnome-session-b. Usuwanie $prac lub po prostu ps -e | grep 'gnome-session'. Po tych zmianach skrypt działa. DostajęGNOME 3.26.2
nath

1

To prawdopodobnie zależy od sytuacji. Jeśli wiesz, który menedżer wyświetlania jest używany, być może ten umieszcza te informacje w zmiennej środowiskowej.

Jeśli tak nie jest, myślę, że musisz sprawdzić każdy DE, który chcesz móc zidentyfikować. Wszyscy powinni wprowadzić własne zmienne środowiskowe.


Zastanawiam się, czy echo ${DESKTOP_SESSION:0:1}to by się udało? O ile mogłem przetestować, zwraca udla Unity i xdla XFCE. Mam nadzieję, że niektórzy ludzie dołączą do KDE i innych komputerów stacjonarnych.
Serge Stroobandt

1
@ on4aa To echo ${DESKTOP_SESSION} kde-plasma-safedla mojego KDE. Dlaczego „bezpieczny” ...
Hauke ​​Laging

Czy jest tu jakiś użytkownik Linux Mint Mate / Cinnamon? E17, LXDE itp. Są również mile widziane ...
Serge Stroobandt

1

Jeśli zmienna środowiskowa XDG_CURRENT_DESKTOPjest dostępna, powinna ci to powiedzieć.

# echo $XDG_CURRENT_DESKTOP
KDE

1
Nie jest to niespodzianką, ale tylko dlatego, aby inni zdawali sobie sprawę z tego, że omijanie tego pytania i odpowiedzi: nie istnieje w GNOME DE.
slm

Rzeczywiście, z naciskiem na „jeśli dostępne”. Zobacz także tę odpowiedź Askubuntu .
Serge Stroobandt

1

Możesz poszukać uruchomionych Xorgprocesów. Rodzicem tego powinien być Twój menedżer wyświetlania. Jego potomkowie powinni wskazać, jakie środowisko pulpitu działa. W moim systemie menedżer wyświetlania wykonuje się sam (z różnymi parametrami). To następnie spawnujex-session-manager które jest dowiązane symbolicznie xfce4-session. To może wystarczyć, ale wszystkie jej dzieci są powiązane z moim środowiskiem graficznym. Znalezienie ich za pomocą drzewa procesów powinno być najlepszym sposobem na wykluczenie elementów innych systemów okien uruchomionych przez różne programy (lub być może celowo).

Moją pierwszą myślą było to, że najlepiej byłoby poszukać menedżera okien powiązanego ze środowiskiem pulpitu, ale często można skonfigurować inny do uruchamiania (np. xmonadW Gnome), więc nie jest to niezawodne. Najlepiej jest szukać tego, który zarządza rzeczywistym pulpitem, npxfdesktop Dowolnym elementem środowiska pulpitu, którego faktycznie potrzebujesz, aby skrypt działał :)

Przykład

Oto przykład użycia procps-ng ( -Ci --ppidnie są POSIX). Zakłada, że ​​jest to tylko jeden przypadek Xorg.

To tylko przykład, który działa na pulpicie Xfce. Pełny działający przykład wymaga zbadania procesów używanych przez każdy system stacjonarny, podobnie jak większość innych rozwiązań wymaga zbadania, w jaki sposób zmienne środowiskowe są ustawiane w różnych innych systemach stacjonarnych.

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

To zwraca unknownna Ubuntu.
Serge Stroobandt

@ on4aa, to nie miało być kompletne rozwiązanie. To miał być przykład, który działa na pulpicie xfce. Pełny działający przykład wymaga zbadania procesów używanych przez każdy system stacjonarny. Myślałem, że byłoby to oczywiste po przeczytaniu kodu.
Graeme

@Greame Masz rację; Byłem trochę za szybki i przeoczyłem niedokończony another_desktopwynik.
Serge Stroobandt

1

Z całego eksperymentu opisanego w licznych komentarzach uważam, że moim obowiązkiem jako OP jest wypracowanie konsensusu. (Zapewniam, chętnie przejrzę tę odpowiedź, jeśli dostępne będą kontrastujące dane).

Na razie wydaje się, że najlepiej jest przejąć inicjatywę od $XDG_CURRENT_DESKTOPmomentu zdefiniowania tej zmiennej. Jeśli nie, $XDG_DATA_DIRSmoże podać żądane informacje, bardziej niż pierwszą literę ${DESKTOP_SESSION:0:1}.


I nie mają XDG_CURRENT_DESKTOP. Myślę, że głównym problemem z tymi zmiennymi są zmienne, ponieważ są one ustawiane przez menedżera wyświetlania, a nie środowisko pulpitu, a więc występuje pewna niespójność. Kiedy wybieram domyślną sesję (xfce) z lightdm echo $DESKTOP_SESSIONdaje, lightdm-xsessionco jest połączeniem lightdmi x-session-manager, proces użyty do uruchomienia mojego pulpitu (symlinkowany xfce4-session). Wyobrażam sobie, że instalacja z inną domyślną sesją po prostu użyje innego dowiązania symbolicznego i da to samoDESKTOP_SESSION
Graeme

W szczególności, jeśli konkretnie wybiorę XFCE lub Gnome z menedżera wyświetlania, DESKTOP_SESSIONfaktycznie powiem xfcelubgnome
Graeme

1
To rozwiązanie nadal mocno opiera się na dystrybucjach opartych na Debianie. Żadna z omawianych metod nie działa na żadnej z dystrybucji opartych na Red Hacie, do których mam dostęp (Fedora, CentOS itp.).
slm

1

Działa to zarówno z Ubuntu 18.10 (kosmiczny) [typ lxqt], jak i Mint 19 (tara) [typ cynamonu]:

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

Przechwyć wynik do zmiennej i wykonaj dalszy niezbędny kod za pomocą zdolnej logiki analitycznej (case stmt, if / then), która obejmuje dowolne / wszystkie rozpoznane typy stamtąd; i / lub działają z wdziękiem, gdy używane są nierozpoznane typy.


Współpracuje także z Xubuntu LTS 18.04.
Serge Stroobandt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.