Làm thế nào để phát hiện môi trường máy tính để bàn trong tập lệnh bash?


24

Tôi đang viết một bashkịch bản cần biết môi trường máy tính để bàn nào (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, Gnome2, Gnome3, ...) đang chạy.

Làm thế nào tôi có thể có được thông tin đó?


1
điều đó thật khó bởi vì ngay cả khi bạn đang ở trong một phiên Gnome và mới bắt đầu một chương trình KDE như kwrite, tất cả các cơ sở hạ tầng KDE như KDE daemon và kdeinit sẽ chạy.
Thorsten Staerk

3
Bạn khá nhiều không thể, không đáng tin cậy. Tại sao bạn cần phải biết? Điều này trông giống như một vấn đề XY .
Gilles 'SO- ngừng trở thành ác quỷ'

@Gilles Câu hỏi hay. Tôi đang viết một kịch bản đặc biệt cho xplanetvà muốn tự động làm mới nền màn hình với các lệnh dành riêng cho môi trường máy tính để bàn. Nếu bạn muốn đăng một câu trả lời cho vấn đề đó , xin vui lòng, hãy theo liên kết.
Serge Stroobandt

Câu trả lời:


11

Vấn đề chính với việc kiểm tra DESKTOP_SESSIONlà nó được đặt bởi trình quản lý hiển thị thay vì phiên máy tính để bàn và có thể không nhất quán. Đối với lightdmDebian, các giá trị đến từ tên của các tệp trong /usr/share/xsessions/. DESKTOP_SESSIONphản ánh môi trường máy tính để bàn nếu một lựa chọn cụ thể được thực hiện khi đăng nhập, tuy nhiên lightdm-xsessionluôn được sử dụng phiên mặc định.

GDMSESSIONlà một lựa chọn khác, nhưng dường như có một tình huống tương tự (nó có cùng giá trị DESKTOP_SESSIONvới tôi).

XDG_CURRENT_DESKTOPcó vẻ như là một lựa chọn tốt, tuy nhiên hiện tại nó không nằm trong tiêu chuẩn XDG và do đó không phải lúc nào cũng được thực hiện. Xem ở đây để thảo luận về điều này. Câu trả lời này hiển thị các giá trị của nó cho các bản phân phối / máy tính để bàn khác nhau, tôi cũng có thể xác nhận rằng nó hiện không có sẵn cho tôi trên XFCE.

Dự phòng hợp lý cho việc XDG_CURRENT_DESKTOPkhông tồn tại sẽ là thử XDG_DATA_DIRS. Được cung cấp các tệp dữ liệu cho môi trường máy tính để bàn được cài đặt trong một thư mục mang tên của nó, phương pháp này sẽ hoạt động. Điều này hy vọng sẽ là trường hợp cho tất cả các distro / máy tính để bàn!

Các thử nghiệm sau (với GNU grep) cho XFCE, KDE và Gnome:

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

Tương thích POSIX:

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

Để kết hợp với kiểm tra 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"

Tôi thích điều này. Theo tổng quan này , sẽ chỉ có một vấn đề với Cinnamon. Tuy nhiên, điều này cuối cùng có thể được giải quyết bằng cách mở báo cáo lỗi với Linux Mint.
Serge Stroobandt

@ on4aa MATE không có trong danh sách, nó có thể có cùng một vấn đề. apt-filecũng là một công cụ tốt để xem các máy tính để bàn khác nhau cài đặt vào đâu.
Graeme

1
Giải pháp này vẫn đang nghiêng về các bản phân phối dựa trên Debian. Không có phương pháp nào được thảo luận hoạt động trên bất kỳ phân phối dựa trên Red Hat nào mà tôi có quyền truy cập (Fedora, CentOS, v.v.).
slm

@slm thú vị, XDG_DATA_DIRSkhông tồn tại hay nó chỉ không chứa bất cứ thứ gì hữu ích?
Graeme

1
@slm rất đúng, tôi nghĩ OP có lẽ nên cố gắng làm những gì anh ấy muốn làm cho mỗi máy tính để bàn theo một ||phong cách. Tuy nhiên, câu hỏi này đã được hỏi trên các trang SE khác, tôi nghĩ chúng ta có bộ câu trả lời tốt nhất.
Graeme

10

Phương pháp # 1 - $ DESKTOP_SESSION

Tôi nghĩ bạn có thể tìm ra bằng cách thẩm vấn biến môi trường $DESKTOP_SESSION. Tôi không hoàn toàn tích cực về việc nó được hỗ trợ rộng rãi như thế nào nhưng trong thử nghiệm hạn chế của tôi, nó dường như có sẵn trên Fedora & Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Một lựa chọn khác là $XDG_SESSION_DESKTOPbiến.

Phương pháp # 2 - wmctrl

Ngoài ra còn có phương pháp này sử dụng wmctrl.

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

Tài liệu tham khảo


1
@ on4aa - $GDMSESSIONlàm tôi lo lắng vì có khả năng nó chỉ hướng đến DE đang sử dụng DE dựa trên GDM hoặc Gnome. GDM = Trình quản lý hiển thị Gnome.
slm

1
@ on4aa DESKTOP_SESSIONtrên xfce.
Graeme

1
trên xfce, DESKTOP_SESSION của tôi là default(mint 15)
glenn jackman

1
Debian cũng cho thấy defaultđiều này. Cài đặt mặc định của Gnome 3.
slm

1
$DESKTOP_SESSIONhiển thị defaultcho KDE theo Fedora 20.
Matthew Cline

5

Bạn có thể sử dụng tập lệnh bash này . Nó có thể phát hiện tên và phiên bản môi trường máy tính để bàn.

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

Hoạt động trên Arch Linux
Colin Keenan

Tôi đã đánh cắp ý tưởng của bạn để kiểm tra chỉ Xfce trong kịch bản của tôi:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan

1
điều này đã không làm việc cho tôi trên GNOME Shell 3.26.2tôi có UNKNOWN. Không có kết quả nào khi gnome-session --versionlàm việc cho tôi là gnome-shell --version | awk '{print $3}'tôi cũng không nhận được gì ps -e | grep -E '^.* gnome-session$'. Điều này dường như là vì -bvào cuối gnome-session-b. Loại bỏ các $công trình hoặc chỉ đơn giản ps -e | grep 'gnome-session'. Với sự thay đổi này, kịch bản đang hoạt động. Tôi nhận đượcGNOME 3.26.2
Nath

1

Điều đó có lẽ phụ thuộc vào tình hình. Nếu bạn biết trình quản lý hiển thị nào được sử dụng thì có thể là trình quản lý này sẽ đưa thông tin này vào một biến môi trường.

Nếu đó không phải là trường hợp thì tôi đoán bạn phải kiểm tra mọi DE bạn muốn để có thể xác định. Tất cả trong số họ nên giới thiệu các biến môi trường riêng của họ.


Tôi đang tự hỏi liệu echo ${DESKTOP_SESSION:0:1}sẽ làm gì lừa? Theo như tôi có thể kiểm tra, nó trả về uUnity và xcho XFCE. Hy vọng rằng một số người dân sẽ kêu gọi KDE và các máy tính để bàn khác.
Serge Stroobandt

1
@ on4aa Đó là echo ${DESKTOP_SESSION} kde-plasma-safeKDE của tôi. Tại sao "an toàn" ...
Hauke ​​Laging 23/214

Có một số người dùng Linux Mint Mate / Cinnamon ở đây không? E17, LXDE, v.v. cũng được chào đón ...
Serge Stroobandt

1

Nếu biến môi trường XDG_CURRENT_DESKTOP có sẵn, nó sẽ cho bạn biết.

# echo $XDG_CURRENT_DESKTOP
KDE

1
Không phải là một điều ngạc nhiên nhưng chỉ để những người khác biết rằng vượt qua câu hỏi và trả lời này: không tồn tại trong Gnome DE.
slm

Thật vậy, với sự nhấn mạnh vào "nếu có". Xem thêm câu trả lời Askubfox này .
Serge Stroobandt

1

Bạn có thể tìm kiếm để chạy Xorg quy trình . Cha mẹ của điều này nên là người quản lý hiển thị của bạn. Hậu duệ của nó sẽ đưa ra một dấu hiệu về môi trường máy tính để bàn đang chạy. Trên hệ thống của tôi, trình quản lý hiển thị sẽ tự thực thi (với các tham số khác nhau). Điều này sau đó sinh ra x-session-managerđược liên kết với xfce4-session. Điều này có thể là đủ, nhưng tất cả những đứa trẻ của điều này có liên quan đến môi trường máy tính để bàn của tôi. Tìm kiếm chúng thông qua cây quy trình nên là cách tốt nhất để loại trừ các yếu tố của các hệ thống cửa sổ khác được bắt đầu bởi các chương trình khác nhau (hoặc có thể có chủ ý).

Suy nghĩ đầu tiên của tôi là tốt nhất nên tìm trình quản lý cửa sổ liên kết với môi trường máy tính để bàn của bạn, nhưng thường thì một cái khác có thể được cấu hình để chạy (ví dụ: xmonad trong Gnome) vì vậy điều này không mạnh mẽ. Cái tốt nhất để tìm có lẽ là cái quản lý máy tính để bàn thực tế, ví dụ xfdesktophoặc bất kỳ yếu tố nào của môi trường máy tính để bàn mà bạn thực sự cần để tập lệnh của bạn hoạt động :)

Thí dụ

Dưới đây là một ví dụ sử dụng Procps-ng ( -C--ppidkhông phải là POSIX). Nó giả sử chỉ là một ví dụ của Xorg.

Đây chỉ là một ví dụ hoạt động cho máy tính để bàn xfce. Một ví dụ hoạt động đầy đủ yêu cầu điều tra các quy trình mà mỗi hệ thống máy tính để bàn sử dụng, giống như hầu hết các giải pháp khác yêu cầu điều tra về cách các biến môi trường được đặt trong các hệ thống máy tính để bàn khác.

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

Điều này trả về unknowntrên Ubuntu.
Serge Stroobandt

@ on4aa, đó không có nghĩa là một giải pháp hoàn chỉnh. Đây được cho là một ví dụ hoạt động cho máy tính để bàn xfce. Một ví dụ hoạt động đầy đủ đòi hỏi một cuộc điều tra về các quy trình mà mỗi hệ thống máy tính để bàn sử dụng. Tôi nghĩ rằng điều đó đã rõ ràng từ việc đọc mã.
Graeme

@Greame Bạn nói đúng; Tôi đã hơi quá nhanh và bỏ qua another_desktopkết quả còn dang dở .
Serge Stroobandt

1

Từ tất cả các thử nghiệm được báo cáo trong rất nhiều ý kiến, tôi nghĩ rằng nhiệm vụ của tôi là OP phải đưa ra câu trả lời đồng thuận. (Hãy yên tâm, tôi sẽ vui lòng xem lại câu trả lời này nếu dữ liệu tương phản trở nên khả dụng.)

Hiện tại, có vẻ như tốt nhất để dẫn đầu của chúng tôi từ $XDG_CURRENT_DESKTOPkhi biến này được xác định. Nếu không, $XDG_DATA_DIRScó thể cung cấp thông tin mong muốn, nhiều hơn so với chữ cái đầu tiên của ${DESKTOP_SESSION:0:1}.


Tôi không có XDG_CURRENT_DESKTOP. Tôi nghĩ vấn đề chính với chúng là các biến ở chỗ chúng được đặt bởi trình quản lý hiển thị thay vì môi trường máy tính để bàn và do đó có một số điểm không nhất quán. Khi tôi chọn một phiên mặc định (xfce) với lightdm echo $DESKTOP_SESSIONcho lightdm-xsessionđó là một sự pha trộn của lightdmx-session-manager, quá trình sử dụng để bắt đầu máy tính để bàn của tôi (symlinked đến xfce4-session). Tôi tưởng tượng việc cài đặt với một phiên mặc định khác sẽ chỉ sử dụng một liên kết tượng trưng khác và mang lại kết quả tương tựDESKTOP_SESSION
Graeme

Đáng chú ý, nếu tôi đặc biệt chọn XFCE hoặc Gnome từ trình quản lý hiển thị, DESKTOP_SESSIONthực tế sẽ nói xfcehoặcgnome
Graeme

1
Giải pháp này vẫn đang nghiêng về các bản phân phối dựa trên Debian. Không có phương pháp nào được thảo luận hoạt động trên bất kỳ phân phối dựa trên Red Hat nào mà tôi có quyền truy cập (Fedora, CentOS, v.v.).
slm

1

Điều này hoạt động trên cả Ubuntu 18.10 (vũ trụ) [loại lxqt] và Mint 19 (tara) [loại quế]:

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

Nắm bắt kết quả vào một biến và thực thi mã cần thiết hơn thông qua logic phân tích có khả năng (trường hợp stmt, nếu / sau đó) bao gồm bất kỳ / tất cả các loại được nhận dạng từ đó; và / hoặc chức năng duyên dáng khi các loại không được công nhận đang được sử dụng.


Hoạt động với Xubfox LTS 18.04.
Serge Stroobandt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.