Как определить среду рабочего стола в скрипте bash?

24

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

Как я могу получить эту информацию?

Серж Строобандт
источник
1
это сложно, потому что даже если вы находитесь в сеансе GNOME и только что запустили одну программу KDE, такую ​​как kwrite, вся инфраструктура KDE, такая как демон KDE и kdeinit, будут работать.
Торстен Стаерк
3
Вы в значительной степени не можете, не надежно. Зачем тебе это знать? Это похоже на проблему XY .
Жиль "ТАК - перестань быть злым"
@ Жиль Хороший вопрос. Я пишу специальный скрипт для 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"
Graeme
источник
Мне это нравится. Согласно этому обзору , проблема будет только с корицей. Тем не менее, это может быть в конечном итоге решено открытием отчета об ошибке в Linux Mint.
Серж Строобандт
@ on4aa MATE отсутствует в списке, вероятно, возникла та же проблема. apt-fileЭто также хороший инструмент, чтобы увидеть, куда устанавливаются различные рабочие столы.
Грэм,
1
Это решение по-прежнему сильно зависит от дистрибутивов на основе Debian. Ни один из обсуждаемых методов не работает ни на одном из дистрибутивов Red Hat, к которым у меня есть доступ (Fedora, CentOS и т. Д.).
SLM
@slm интересно, XDG_DATA_DIRSне существует или просто не содержит ничего полезного?
Грэм
1
@slm очень верно, я думаю, что OP, вероятно, лучше пытается делать то, что он хочет сделать для каждого рабочего стола в ||стиле. Тем не менее, этот вопрос был задан на других сайтах SE, я думаю, что у нас есть лучший набор ответов.
Грэм
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

Ссылки

SLM
источник
1
@ on4aa - $GDMSESSIONзаставляет меня нервничать, поскольку, скорее всего, он ориентирован только на DE, которые используют либо GDM, либо DE на основе GNOME. GDM = Диспетчер отображения GNOME.
SLM
1
@ on4aa DESKTOP_SESSIONна xfce .
Грэм,
1
на xfce мой DESKTOP_SESSION default(мята 15)
Гленн Джекман,
1
Debian 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
alexeevdv
источник
Работает над 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в конце gnome-session-b. Удаление $работ или просто просто ps -e | grep 'gnome-session'. С этими изменениями скрипт работает. Я получаюGNOME 3.26.2
nath
1

Это, вероятно, зависит от ситуации. Если вы знаете, какой диспетчер отображения используется, возможно, он помещает эту информацию в переменную среды.

Если это не так, то я думаю, что вы должны проверить все DE, которые вы хотите идентифицировать. Все они должны представить свои собственные переменные среды.

Хауке Лагинг
источник
Мне интересно, echo ${DESKTOP_SESSION:0:1}будет ли делать трюк? Насколько я мог проверить, он возвращается uдля Unity и xдля XFCE. Надеюсь, некоторые люди присоединятся к KDE и другим рабочим столам.
Серж Строобандт
1
@ on4aa Это echo ${DESKTOP_SESSION} kde-plasma-safe для моего KDE. Как бы то ни было "безопасно" ...
Hauke ​​Laging
Есть ли здесь пользователи Linux Mint Mate / Cinnamon? E17, LXDE и т. Д. Также приветствуются ...
Серж Штробандт
1

Если переменная среды XDG_CURRENT_DESKTOPдоступна, она должна сообщить вам.

# echo $XDG_CURRENT_DESKTOP
KDE
Мэтью Клайн
источник
1
Не удивительно, но просто так, что другие знают, что проходящий мимо этого Q & A: не существует в 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
Graeme
источник
Это возвращается unknownв Ubuntu.
Серж Строобандт
@ on4aa, это не было полным решением. Это должен был быть пример, который работает для рабочего стола xfce. Полный рабочий пример требует изучения процессов, которые использует каждая настольная система. Я думал, что это было бы очевидно из чтения кода.
Грэм,
@ Грум, ты прав; Я был слишком быстр и упустил из виду незаконченный 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], так и для Mint 19 (тара) [тип корицы]:

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

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

odoncaoa
источник
Работает также с Xubuntu LTS 18.04.
Серж Строобандт