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?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityI 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?
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"
apt-file
is also a good tool to see where the various desktops install to.
XDG_DATA_DIRS
not exist or does it just not contain anything useful?
||
style. Still this question has been asked on other SE sites, I think we have the best set of answers.
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.
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
$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.
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
ps -e | grep -E '^.* xfce4-session$' > /dev/null
(($? == 0)) && ...
Oct 7, 2014 at 15:42
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
That probably depends on the situation. If you know which display manager is used then it may be that this one puts this information in a environment variable.
If that is not the case then I guess you have to check for every DE you want to be able to identify. All of them should introduce their own environment variables.
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.
Feb 23, 2014 at 16:16
echo ${DESKTOP_SESSION} kde-plasma-safe
for my KDE. Whyever "safe"...
Feb 23, 2014 at 16:23
If the environmental variable XDG_CURRENT_DESKTOP
is available, it should tell you.
# echo $XDG_CURRENT_DESKTOP
KDE
You could look for running Xorg
processes. The parent of this should be your display manager. Its descendants should give an indication of what desktop environment is running. On my system, the display manager executes itself (with different parameters). This then spawns x-session-manager
which is symlinked to xfce4-session
. This may be enough, but all the children of this are related to my desktop environment. Finding them via the process tree should be the best way to exclude elements of other window systems started by various programs (or perhaps deliberately).
My first thought was that it would be be best to look for the window manager associated with your desktop environment, but often a different one can be configured to run (eg xmonad
in Gnome) so this is not robust. The best one to look for is probably the one which manages the actual desktop, eg xfdesktop
or whatever element of the desktop environment you actally need for your script to work :)
Here is an example using procps-ng (-C
and --ppid
are not POSIX). It assumes the is only one instance of Xorg
.
This is just an example that works for the xfce desktop. A full working example requires an investigation in to the processes that each desktop system uses, just as most of the other solutions require investigation into how environmental variables are set in various other desktop systems.
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
another_desktop
outcome.
Feb 24, 2014 at 10:33
From all the experimenting reported in the numerous comments, I think its my duty as the OP to come up with a consensus answer. (Rest assured, I would be happy to review this answer should contrasting data become available.)
For now, it seems best to take our lead from $XDG_CURRENT_DESKTOP
when this variable is defined. If not, $XDG_DATA_DIRS
may provide the desired information, more so than the first letter of ${DESKTOP_SESSION:0:1}
.
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
DESKTOP_SESSION
will actually say xfce
or gnome
This works on both Ubuntu 18.10 (cosmic) [lxqt type] and Mint 19 (tara) [cinnamon type]:
$ set | grep XDG_CURRENT_DESKTOP | tr '[:upper:]' '[:lower:]' | cut -d'=' -f2
Capture the result into a variable, and execute further necessary code via capable analytic logic (case stmt, if/then) which includes any/all recognized types from there; and/or function gracefully when unrecognized types are in use.
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:
XDG_CURRENT_DESKTOP, defined in the Desktop Entry Specification since its version 1.2
XDG_SESSION_DESKTOP, best described in systemd
's PAM
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
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.