如何在bash脚本中检测桌面环境?


24

我正在编写一个bash脚本,该脚本需要知道正在运行哪个桌面环境(XFCE,Unity,KDE,LXDE,Mate,Cinnamon,GNOME2,GNOME3等)。

我如何获得该信息?


1
这很困难,因为即使您处于GNOME会话中并且刚刚启动了一个像kwrite这样的KDE程序,所有KDE基础结构(如KDE守护程序和kdeinit)也将运行。
Thorsten Staerk

3
您几乎不能,不可靠。你为什么要知道?这看起来像XY问题
吉尔(Gilles)'所以

@吉尔斯很好的问题。我正在为其编写专业脚本,xplanet并希望使用特定于桌面环境的命令自动刷新桌面背景。如果您想发布该问题的答案,请点击链接。
Serge Stroobandt 2014年

Answers:


11

检查的主要问题DESKTOP_SESSION是它是由显示管理器而不是桌面会话设置的,并且存在不一致的地方。对于lightdm在Debian上,值来自下的文件名/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打开错误报告来解决。
Serge Stroobandt

@ on4aa MATE不在列表中,它可能有相同的问题。apt-file也是查看各种桌面安装位置的好工具。
Graeme 2014年

1
该解决方案仍然严重依赖于基于Debian的发行版。讨论的方法都无法在我可以访问的任何基于Red Hat的发行版(Fedora,CentOS等)上运行。
slm

@slm有趣,不XDG_DATA_DIRS存在或仅不包含任何有用的内容?
Graeme 2014年

1
@slm非常正确,我认为OP最好尝试以一种||样式为每个桌面做他想做的事情。在其他SE网站上仍然有人问过这个问题,我认为我们有最好的答案。
Graeme 2014年

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让我感到紧张,因为它可能只针对使用GDM或基于GNOME的DE的DE。GDM = GNOME显示管理器。
slm

1
@ on4aa DESKTOP_SESSION在xfce上。
Graeme 2014年

1
在xfce上,我的DESKTOP_SESSION是default(薄荷糖15)
glenn jackman 2014年

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

在Arch Linux上工作
Colin Keenan 2014年

我偷走了您的想法,仅在脚本中检查Xfce:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan 2014年

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}会成功?据我测试,它将返回uUnity和xXFCE。希望有些人会喜欢KDE和其他台式机。
Serge Stroobandt 2014年

1
@ on4aa echo ${DESKTOP_SESSION} kde-plasma-safe用于我的KDE。为什么“安全” ...
Hauke Laging

这里有一些Linux Mint Mate / Cinnamon用户吗?也欢迎E17,LXDE等...
Serge Stroobandt 2014年


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上返回。
Serge Stroobandt 2014年

@ on4aa,这并不是一个完整的解决方案。这应该是适用于xfce桌面的示例。一个完整的工作示例需要调查每个桌面系统使用的进程。我认为从阅读代码中可以明显看出这一点。
Graeme

@Greame你是对的;我太快了,忽略了未完成的another_desktop结果。
Serge Stroobandt,2014年

1

从众多评论中报告的所有实验中,我认为作为OP的职责是我要达成共识。(请放心,如果有对比数据可用,我很乐意复查此答案。)

就目前而言,最好是从$XDG_CURRENT_DESKTOP定义此变量的时候开始。如果不是,则$XDG_DATA_DIRS可以提供所需的信息,而不是的第一个字母${DESKTOP_SESSION:0:1}


我没有XDG_CURRENT_DESKTOP。我认为这些变量的主要问题在于变量是由显示管理器而不是桌面环境设置的,因此存在一些不一致之处。当我选择用lightdm默认会话(XFCE)echo $DESKTOP_SESSION给出了lightdm-xsession这是一个融合lightdmx-session-manager,用于启动我的桌面(符号链接的过程xfce4-session)。我想象使用不同的默认会话进行安装将仅使用不同的符号链接并产生相同的结果DESKTOP_SESSION
Graeme 2014年

值得注意的是,如果我专门从显示管理器中选择XFCE或侏儒,DESKTOP_SESSION实际上说的xfce还是gnome
格雷姆

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

将结果捕获到一个变量中,然后通过功能强大的分析逻辑(如果是/则为案例stmt)执行进一步的必要代码,其中包括来自那里的任何/所有已识别类型;和/或在使用无法识别的类型时正常运行。


也可以与Xubuntu LTS 18.04一起使用。
Serge Stroobandt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.