How to detect the desktop environment in a bash script?

26,127

Solution 1

The main problem with checking the DESKTOP_SESSION is that it is set by the display manager rather than the desktop session and is subject to inconsistencies. For lightdm on Debian, the values come from the names of files under /usr/share/xsessions/. DESKTOP_SESSION reflects the desktop environment if a specific selection is made at log in, however the lightdm-xsession is always used the default session.

GDMSESSION is another option, but seems to have a similar predicament (it is the same value as DESKTOP_SESSION for me).

XDG_CURRENT_DESKTOP looks like a good choice, however it is currently not in the XDG standard and thus not always implemented. See here for a discussion of this. This answer shows its values for different distros/desktops, I can also confirm it is currently not available for me on XFCE.

The reasonable fallback for XDG_CURRENT_DESKTOP not existing would be to try XDG_DATA_DIRS. Provided the data files for the desktop environment are installed in a directory bearing its name, this approach should work. This will hopefully be the case for all distros/desktops!

The following (with GNU grep) tests for XFCE, KDE and Gnome:

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

POSIX compatible:

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

To combine with checking 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"

Solution 2

Method #1 - $DESKTOP_SESSION

I think you can find out by interrogating the environment variable $DESKTOP_SESSION. I'm not entirely positive how widely supported this is but in my limited testing it appears to be available on Fedora & Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Another choice is the $XDG_SESSION_DESKTOP variable.

Method #2 - wmctrl

There is also this method that makes use of wmctrl.

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

References

Solution 3

You can use this bash script. It can detect desktop environment name and version.

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

Solution 4

Standards evolved a lot since question was made in 2014.

For 2021, my recommendation is: use only the official $XDG_CURRENT_DESKTOP.

Be careful that officially it is a colon-separated list (like $PATH), so don't assume it only contains a single value, even if it is in most DEs. For example, Ubuntu's Unity set it to Unity:Unity7:ubuntu.

If you prefer to handle a single value, use $XDG_SESSION_DESKTOP.

Official standards:

Other related environment variables should be considered legacy by now.

A bash function to properly check a given string against the current desktop environment:

# Encapsulates the mess that DE detection was, is, or will ever be...
# Without arguments, check if in a Desktop Environment at all
# Subshell is intentional so we don't have to save/restore IFS
# Case-insensitive comparison
is_desktop_environment() (
    local de=${1:-}
    local DEs=${XDG_CURRENT_DESKTOP:-}

    # Shortcut: If de is empty, check if empty DEs
    if [[ -z "$de" ]]; then if [[ "$DEs" ]]; then return; else return 1; fi; fi

    # Lowercase both
    de=${de,,}; DEs=${DEs,,}

    # Check de against each DEs component
    IFS=:; for DE in $DEs; do if [[ "$de" == "$DE" ]]; then return; fi; done

    # Not found
    return 1
)

Testing:

for de in "" Ubuntu Gnome KDE Unity; do
    if is_desktop_environment "$de"; then
        echo "Yes, this is ${de:-a DE}"
    else
        echo "No,  this is not ${de:-a DE}"
    fi
done

Yes, this is a DE
Yes, this is Ubuntu
No,  this is not Gnome
No,  this is not KDE
Yes, this is Unity

Solution 5

If the environmental variable XDG_CURRENT_DESKTOP is available, it should tell you.

# echo $XDG_CURRENT_DESKTOP
KDE
Share:
26,127

Related videos on Youtube

Serge Stroobandt
Author by

Serge Stroobandt

Updated on September 18, 2022

Comments

  • Serge Stroobandt
    Serge Stroobandt almost 2 years

    I am writing a bash script that needs to know which desktop environment (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3,... ) is running.

    How can I obtain that information?

    • Thorsten Staerk
      Thorsten Staerk over 10 years
      that is hard because even if you are in a GNOME session and just started one KDE program like kwrite all the KDE infrastructure like KDE daemon and kdeinit will be running.
    • Serge Stroobandt
      Serge Stroobandt over 10 years
      @Gilles Good question. I am writing a speciality script for xplanet and would like to automatically refresh the desktop background with commands specific to the desktop environment. If you like to post an answer to that problem, please, follow the link.
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    I am wondering whether echo ${DESKTOP_SESSION:0:1} would do the trick? As far as I could test, it returns u for Unity and x for XFCE. Hopefully some folk will chime in for KDE and other desktops.
  • Hauke Laging
    Hauke Laging over 10 years
    @on4aa It's echo ${DESKTOP_SESSION} kde-plasma-safe for my KDE. Whyever "safe"...
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    I am truncating at the first letter because plain echo $DESKTOP_SESSION yields xubuntu on my machine.
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    Are there some Linux Mint Mate/Cinnamon users here? E17, LXDE, etc. are also welcome...
  • Graeme
    Graeme over 10 years
    Mine gives lightdm-xsession
  • slm
    slm over 10 years
    This approach came from this AU Q&A: askubuntu.com/questions/72549/…
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    Especially this answer is very informative. Could it be that $GDMSESSION consistently yields the same results as $DESKTOP_SESSION?
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    @Graeme Which variable on what desktop?
  • slm
    slm over 10 years
    @on4aa - $GDMSESSION makes me nervous since it's likely only geared towards DE that are either using GDM or GNOME based DE. GDM = GNOME Display Manager.
  • Graeme
    Graeme over 10 years
    @on4aa DESKTOP_SESSION on xfce.
  • Angel Todorov
    Angel Todorov over 10 years
    on xfce, my DESKTOP_SESSION is default (mint 15)
  • slm
    slm over 10 years
    Debian showed default for this too. A default install of GNOME 3.
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    wmctrl -m on Ubuntu (Unity): Name: Metacity
  • Matthew Cline
    Matthew Cline over 10 years
    $DESKTOP_SESSION shows default for KDE under Fedora 20.
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    This returns unknown on Ubuntu.
  • Graeme
    Graeme over 10 years
    @on4aa, that was not meant to be a complete solution. This was supposed to be an example that works for the xfce desktop. A full working example requires an investigation in to the processes that each desktop system uses. I thought that would have been obvious from reading the code.
  • Graeme
    Graeme over 10 years
    I have no XDG_CURRENT_DESKTOP. I think the main problem with these is variables in that they are set by the display manager rather than the desktop environment and so there is some inconsistency. When I choose a default session (xfce) with lightdm echo $DESKTOP_SESSION gives lightdm-xsession which is an amalgamation of lightdm and x-session-manager, the process used to start my desktop (symlinked to xfce4-session). I imagine installing with a different default session will just use a different symlink and yield the same DESKTOP_SESSION
  • Graeme
    Graeme over 10 years
    Notably, if I specifically choose XFCE or Gnome from the display manager, DESKTOP_SESSION will actually say xfce or gnome
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    @Greame You are right; I was a bit too quick and overlooked the unfinished another_desktop outcome.
  • Serge Stroobandt
    Serge Stroobandt over 10 years
    I like this. According to this overview, there will only be a problem with Cinnamon. However, this might eventually be resolved by opening a bug report with Linux Mint.
  • Graeme
    Graeme over 10 years
    @on4aa MATE is not on the list, it is likely to have the same issue. apt-file is also a good tool to see where the various desktops install to.
  • slm
    slm over 10 years
    This solution is still leaning heavily towards Debian based distros. None of the methods discussed work on any of the Red Hat based distros I have access to (Fedora, CentOS, etc.).
  • slm
    slm over 10 years
    This solution is still leaning heavily towards Debian based distros. None of the methods discussed work on any of the Red Hat based distros I have access to (Fedora, CentOS, etc.).
  • Graeme
    Graeme over 10 years
    @slm interesting, does XDG_DATA_DIRS not exist or does it just not contain anything useful?
  • slm
    slm over 10 years
    @Graeme - Doesn't exist. This was kind of my finding w/ my A too. There seems to be a divide b/w the Debian vs. RH distros at this level. I think Gilles comment is actually spot on though, this is a XY problem.
  • Graeme
    Graeme over 10 years
    @slm very true, I think the OP is probably better trying to do what he wants to do for each desktop in a || style. Still this question has been asked on other SE sites, I think we have the best set of answers.
  • Graeme
    Graeme over 10 years
    @slm, what about my process tree walking stuff, how would that fare?
  • slm
    slm over 10 years
    @Graeme - do you mean your script? That returns a blank line.
  • Graeme
    Graeme over 10 years
    @slm, my other answer. If it the script returns a blank line then its broken :(. It will only work for xfce, but it is the process of searching descendants of the parent of Xorg I'm asking about.
  • Colin Keenan
    Colin Keenan over 9 years
    On Arch Linux with Xfce, echo "$XDG_DATA_DIRS" returns /usr/local/share:/usr/share, and so is not useful.
  • Colin Keenan
    Colin Keenan over 9 years
    $DESKTOP_SESSION worked on Arch Linux Xfce.
  • Colin Keenan
    Colin Keenan over 9 years
    Works on Arch Linux
  • Colin Keenan
    Colin Keenan over 9 years
    I stole your idea to check just for Xfce in my script: ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
  • nath
    nath over 6 years
    this did not work for me on GNOME Shell 3.26.2 I got UNKNOWN. No output from gnome-session --version working for me is gnome-shell --version | awk '{print $3}' I also did not get anything out of ps -e | grep -E '^.* gnome-session$'. This seems to be because of -b at the end of gnome-session-b. Removing the $ works or just simply ps -e | grep 'gnome-session'. With this changes the script is working. I get GNOME 3.26.2
  • nath
    nath over 6 years
    $XDG_CURRENT_DESKTOP works for me on GNOME Shell 3.26.2 - Debian "buster" and on xfce 4.10.1 - Debian "jessie". $XDG_DATA_DIRS is empty on both!
  • Nathaniel M. Beaver
    Nathaniel M. Beaver about 6 years
    $XDG_CURRENT_DESKTOP was specified in version 1.2 of the freedesktop standard.
  • Serge Stroobandt
    Serge Stroobandt over 5 years
    Works also with Xubuntu LTS 18.04.