Як виявити середовище робочого столу в скрипті bash?


24

Я пишу bashсценарій, який повинен знати, яке середовище робочого столу (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) працює.

Як я можу отримати цю інформацію?


1
це важко, тому що навіть якщо ви перебуваєте на сесії GNOME і тільки що запустили одну програму KDE, наприклад, kwrite всю інфраструктуру KDE, наприклад, KDE демона та kdeinit.
Thorsten Staerk

3
Ви майже не можете, не надійно. Чому потрібно знати? Це виглядає як проблема XY .
Жил "ТАК - перестань бути злим"

@Gilles Добре запитання. Я пишу сценарій спеціальності для xplanetі хочу автоматично оновити фон робочого столу командами, характерними для середовища робочого столу. Якщо ви хочете опублікувати відповідь на цю проблему , перейдіть за посиланням.
Серж Стротобандт

Відповіді:


11

Основна проблема при перевірці DESKTOP_SESSIONполягає в тому, що він встановлюється диспетчером дисплеїв, а не сеансом робочого столу і є предметом невідповідностей. Для lightdmDebian значення походять від імен файлів під /usr/share/xsessions/. DESKTOP_SESSIONвідображає середовище робочого столу, якщо під час входу робиться певний вибір, проте lightdm-xsessionсеанс завжди використовується за замовчуванням.

GDMSESSIONінший варіант, але, схоже, має схоже становище (це те саме значення, що і DESKTOP_SESSIONдля мене).

XDG_CURRENT_DESKTOPвиглядає як хороший вибір, однак на даний момент він не відповідає стандарту XDG і тому не завжди реалізується. Дивіться тут для обговорення цього питання. Ця відповідь показує її значення для різних дистрибутивів / настільних ПК, я також можу підтвердити, що вона наразі недоступна для мене на XFCE.

Справжнім запасом для XDG_CURRENT_DESKTOPнеіснуючих було б спробувати XDG_DATA_DIRS. Якщо файли даних для середовища робочого столу встановлені в каталозі, що має його ім'я, такий підхід повинен працювати. Сподіваємось, це стосується всіх дистрибутивів / настільних комп'ютерів!

Наступні (з GNU grep) тести для XFCE, KDE та Gnome:

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

POSIX сумісний:

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

Щоб поєднати з перевіркою 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"

Мені подобається це. Згідно з цим оглядом , з Корицею буде лише проблема. Однак це врешті може бути вирішено шляхом відкриття звіту про помилки з Linux Mint.
Серж Стройбандт

@ on4aa MATE відсутній у списку, ймовірно, це те саме питання. apt-fileце також хороший інструмент, щоб побачити, куди встановлюються різні настільні комп'ютери.
Graeme

1
Це рішення все ще сильно схиляється до дистрибутивів на основі Debian. Жоден із обговорених методів не працює над будь-яким із дистрибутивів, заснованих на Red Hat, до яких я маю доступ (Fedora, CentOS тощо).
slm

@slm цікаво, XDG_DATA_DIRSне існує чи він просто не містить нічого корисного?
Graeme

1
@slm дуже правда, я думаю, що ОП, ймовірно, краще намагається робити те, що він хоче зробити для кожного робочого столу в ||стилі. І все-таки це питання було задано на інших веб-сайтах ДП, я думаю, що у нас найкращий набір відповідей.
Graeme

10

Спосіб №1 - $ DESKTOP_SESSION

Я думаю, що це можна дізнатися, допитуючи змінну середовища $DESKTOP_SESSION. Я не зовсім впевнений, наскільки це широко підтримується, але в моїх обмежених тестах це здається, що вони доступні у Fedora та Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Інший вибір - $XDG_SESSION_DESKTOPзмінна.

Спосіб №2 - wmctrl

Існує також цей метод, який використовує wmctrl.

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

Список літератури


1
@ on4aa - $GDMSESSIONнервує мене, оскільки це, ймовірно, орієнтоване лише на DE, які використовують GDM або DE на основі GNOME. GDM = Диспетчер дисплеїв GNOME.
slm

1
@ on4aa DESKTOP_SESSIONна xfce.
Graeme

1
на xfce, мій DESKTOP_SESSION є default(м'ята 15)
glenn jackman

1
Дебіан показав і defaultдля цього. Встановлення за замовчуванням GNOME 3.
slm

1
$DESKTOP_SESSIONпоказує defaultдля KDE під Fedora 20.
Меттью Клайн

5

Ви можете використовувати цей скрипт bash . Він може виявити ім'я та версію робочого середовища.

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

Працює над Arch Linux
Колін Кінан

Я вкрав вашу ідею перевірити лише на Xfce за моїм сценарієм:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Колін Кінан

1
це не працює для мене на GNOME Shell 3.26.2мене UNKNOWN. Немає результатів gnome-session --versionроботи для мене, gnome-shell --version | awk '{print $3}'я теж нічого не отримав ps -e | grep -E '^.* gnome-session$'. Це, мабуть, тому, що -bв кінці 2010 року gnome-session-b. Видалення $творів або просто просто ps -e | grep 'gnome-session'. З цими змінами сценарій працює. Я отримуюGNOME 3.26.2
Натхо

1

Це, мабуть, залежить від ситуації. Якщо ви знаєте, який диспетчер дисплеїв використовується, то, можливо, цей розміщує цю інформацію в змінній середовища.

Якщо це не так, то, мабуть, вам доведеться перевірити кожну DE, яку ви хочете мати можливість ідентифікувати. Усі вони повинні представити власні змінні середовища.


Мені цікаво, чи echo ${DESKTOP_SESSION:0:1}зробив би трюк? Наскільки я міг перевірити, він повертається uдля Unity та xдля XFCE. Сподіваємось, деякі люди призиватимуться до KDE та інших настільних ПК.
Серж Стройбандт

1
@ on4aa Це echo ${DESKTOP_SESSION} kde-plasma-safeдля мого KDE. Чому б "безпечно" ...
Хоке Лагінг

Чи є тут деякі користувачі Linux Mint Mate / Cinnamon? E17, LXDE та ін. Також вітаються ...
Серж Стротобандт

1

Якщо екологічна змінна XDG_CURRENT_DESKTOPє, вона повинна вам сказати.

# echo $XDG_CURRENT_DESKTOP
KDE

1
Не сюрприз, але просто інші знають, що проходження повз цього питання: немає в GNOME DE.
slm

Дійсно, з акцентом на "за наявності". Дивіться також цю відповідь Askubuntu .
Серж Стротобандт

1

Ви можете шукати запущені Xorgпроцеси. Батьком цього повинен бути ваш менеджер дисплеїв. Її нащадки повинні вказувати на те, яке середовище робочого столу працює. У моїй системі диспетчер дисплеїв виконує себе (з різними параметрами). Потім x-session-managerце нерести, які посилаються наxfce4-session . Цього може бути достатньо, але всі діти цього стосуються мого середовища на робочому столі. Пошук їх через дерево процесів повинен бути найкращим способом виключення елементів інших віконних систем, запущених різними програмами (або, можливо, навмисно).

Перша моя думка полягала в тому, що було б найкраще шукати вікно-менеджер, пов’язаний із робочим середовищем робочого столу, але часто можна налаштувати інший для запуску (наприклад, xmonadу Gnome), тому це не є надійним. Найкраще шукати - це, напевно, той, який керує фактичним робочим столом, наприклад, xfdesktopабо будь-яким елементом робочого середовища, який вам потрібен, щоб ваш сценарій працював :)

Приклад

Ось приклад використання procps-ng ( -Cі --ppidне є POSIX). Він передбачає лише один екземпляр Xorg.

Це лише приклад, який працює на робочому столі xfce. Повний робочий приклад вимагає дослідження процесів, якими користується кожна настільна система, як і більшість інших рішень потребує дослідження того, як встановлюються змінні середовища в різних інших настільних системах.

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

Це повертається unknownна Ubuntu.
Серж Стройбандт

@ on4aa, це не мало бути повним рішенням. Це повинен був бути прикладом, який працює для робочого столу xfce. Повний робочий приклад вимагає вивчення процесів, якими користується кожна настільна система. Я подумав, що це було б очевидно з читання коду.
Graeme

@Greame Ви маєте рацію; Я був занадто швидким і не помітив незакінчений another_desktopрезультат.
Серж Стройбандт

1

Зважаючи на всі експерименти, про які повідомлялося в численних коментарях, я вважаю своїм обов'язком як ОП створити консенсусну відповідь. (Будьте впевнені, я би радий переглянути цю відповідь у разі наявності контрастних даних.)

На даний момент, здається, найкраще взяти на себе керівництво з $XDG_CURRENT_DESKTOPтих пір, коли ця змінна буде визначена. Якщо ні, $XDG_DATA_DIRSможе надати бажану інформацію, тим більше, ніж перша літера ${DESKTOP_SESSION:0:1}.


У мене немає XDG_CURRENT_DESKTOP. Я думаю, що головна проблема цих змінних полягає в тому, що вони встановлюються диспетчером дисплеїв, а не середовищем робочого столу, і тому є певна непослідовність. Коли я вибираю сеанс за замовчуванням (xfce) з lightdm echo $DESKTOP_SESSIONдає, lightdm-xsessionщо є об'єднанням lightdmі x-session-manager, процес, який використовується для запуску мого робочого столу (з посиланням на xfce4-session). Я думаю, що встановлення з іншим сеансом за замовчуванням просто використовуватиме інше символьне посилання та отримає те самеDESKTOP_SESSION
Graeme

Примітно, якщо я спеціально виберу XFCE або Gnome з диспетчера дисплеїв, DESKTOP_SESSIONнасправді скажу xfceабоgnome
Graeme

1
Це рішення все ще сильно схиляється до дистрибуцій, заснованих на Debian. Жоден із обговорених методів не працює над будь-яким із дистрибутивів, заснованих на Red Hat, до яких я маю доступ (Fedora, CentOS тощо).
slm

1

Це працює як для Ubuntu 18.10 (космічний) [тип lxqt], так і для монетного двору 19 (тара) [тип кориці]:

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

Захопіть результат у змінну та виконайте подальший необхідний код за допомогою здатної аналітичної логіки (case stmt, якщо / тоді), яка включає в себе будь-які / всі розпізнані типи звідти; та / або функціонувати витончено, коли використовуються нерозпізнані типи.


Також працює з Xubuntu LTS 18.04.
Серж Стротобанд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.