Bagaimana cara mendeteksi lingkungan desktop dalam skrip bash?

24

Saya menulis bashskrip yang perlu tahu lingkungan desktop mana (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ...) sedang berjalan.

Bagaimana saya bisa mendapatkan informasi itu?

Serge Stroobandt
sumber
1
itu sulit karena walaupun Anda berada dalam sesi GNOME dan baru memulai satu program KDE seperti kwrite semua infrastruktur KDE seperti daemon dan kdeinit KDE akan berjalan.
Thorsten Staerk
3
Anda tidak bisa, tidak andal. Mengapa Anda perlu tahu? Ini terlihat seperti masalah XY .
Gilles 'SO- stop being evil'
@ Gilles Pertanyaan bagus. Saya sedang menulis skrip khusus untuk xplanetdan ingin menyegarkan latar belakang desktop secara otomatis dengan perintah khusus untuk lingkungan desktop. Jika Anda ingin mengirim jawaban untuk masalah itu , silakan ikuti tautannya.
Serge Stroobandt

Jawaban:

11

Masalah utama dengan memeriksa DESKTOP_SESSIONadalah bahwa hal itu diatur oleh manajer tampilan daripada sesi desktop dan tunduk pada inkonsistensi. Untuk lightdmdi Debian, nilai berasal dari nama file di bawah /usr/share/xsessions/. DESKTOP_SESSIONmencerminkan lingkungan desktop jika pilihan tertentu dibuat saat login, namun lightdm-xsessionselalu menggunakan sesi default.

GDMSESSIONadalah pilihan lain, tetapi tampaknya memiliki kesulitan yang sama (itu adalah nilai yang sama dengan DESKTOP_SESSIONsaya).

XDG_CURRENT_DESKTOPsepertinya pilihan yang baik, namun saat ini tidak dalam standar XDG dan dengan demikian tidak selalu diterapkan. Lihat di sini untuk diskusi tentang ini. Jawaban ini menunjukkan nilainya untuk distro / desktop yang berbeda, saya juga dapat mengonfirmasi saat ini tidak tersedia untuk saya di XFCE.

Fallback masuk akal untuk XDG_CURRENT_DESKTOPtidak ada akan mencoba XDG_DATA_DIRS. Asalkan file data untuk lingkungan desktop dipasang di direktori bertuliskan namanya, pendekatan ini harus bekerja. Mudah-mudahan ini akan menjadi kasus untuk semua distro / desktop!

Tes berikut (dengan GNU grep) untuk XFCE, KDE dan Gnome:

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

Kompatibel dengan POSIX:

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

Untuk menggabungkan dengan memeriksa 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
sumber
Saya suka ini. Menurut tinjauan ini , hanya akan ada masalah dengan Kayu Manis. Namun, ini akhirnya dapat diatasi dengan membuka laporan bug dengan Linux Mint.
Serge Stroobandt
@ on4aa MATE tidak ada dalam daftar, kemungkinan memiliki masalah yang sama. apt-filejuga merupakan alat yang baik untuk melihat di mana berbagai desktop diinstal.
Graeme
1
Solusi ini masih condong ke arah distro berbasis Debian. Tak satu pun dari metode yang dibahas bekerja pada distro berbasis Red Hat yang saya miliki aksesnya (Fedora, CentOS, dll.).
slm
@slm menarik, XDG_DATA_DIRStidak ada atau tidak mengandung sesuatu yang bermanfaat?
Graeme
1
@slm sangat benar, saya pikir OP mungkin lebih baik mencoba melakukan apa yang dia ingin lakukan untuk setiap desktop dengan ||gaya. Masih pertanyaan ini telah diajukan di situs SE lainnya, saya pikir kami memiliki set jawaban terbaik.
Graeme
10

Metode # 1 - $ DESKTOP_SESSION

Saya pikir Anda bisa mengetahuinya dengan menginterogasi variabel lingkungan $DESKTOP_SESSION. Saya tidak sepenuhnya positif seberapa luas ini didukung tetapi dalam pengujian terbatas saya tampaknya tersedia di Fedora & Ubuntu.

$ echo $DESKTOP_SESSION
gnome

Pilihan lain adalah $XDG_SESSION_DESKTOPvariabel.

Metode # 2 - wmctrl

Ada juga metode ini yang memanfaatkan wmctrl.

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

Referensi

slm
sumber
1
@ on4aa - $GDMSESSIONmembuat saya gugup karena sepertinya hanya diarahkan pada DE yang menggunakan DE berbasis GDM atau GNOME. GDM = Manajer Tampilan GNOME.
slm
1
@ on4aa DESKTOP_SESSIONdi xfce.
Graeme
1
pada xfce, DESKTOP_SESSION saya adalah default(mint 15)
glenn jackman
1
Debian juga menunjukkan defaultini. Instalasi default GNOME 3.
slm
1
$DESKTOP_SESSIONmenunjukkan defaultuntuk KDE di bawah Fedora 20.
Matthew Cline
5

Anda dapat menggunakan skrip bash ini . Itu dapat mendeteksi nama dan versi lingkungan desktop.

#!/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
sumber
Bekerja di Arch Linux
Colin Keenan
Saya mencuri ide Anda untuk memeriksa hanya untuk Xfce dalam skrip saya:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan
1
ini tidak bekerja untuk saya pada GNOME Shell 3.26.2aku UNKNOWN. Tidak ada hasil dari gnome-session --versionbekerja untuk saya adalah gnome-shell --version | awk '{print $3}'saya juga tidak mendapatkan apa-apa ps -e | grep -E '^.* gnome-session$'. Ini sepertinya karena -bpada akhir gnome-session-b. Menghapus $karya atau sekadar ps -e | grep 'gnome-session'. Dengan perubahan ini skrip berfungsi. Saya mendapatkanGNOME 3.26.2
nath
1

Itu mungkin tergantung pada situasinya. Jika Anda tahu manajer tampilan mana yang digunakan maka mungkin ini yang menempatkan informasi ini dalam variabel lingkungan.

Jika bukan itu masalahnya maka saya kira Anda harus memeriksa setiap DE yang ingin Anda identifikasi. Mereka semua harus memperkenalkan variabel lingkungan mereka sendiri.

Hauke ​​Laging
sumber
Saya bertanya-tanya apakah echo ${DESKTOP_SESSION:0:1}akan melakukan trik? Sejauh yang saya bisa uji, itu mengembalikan uuntuk Unity dan xuntuk XFCE. Semoga beberapa orang akan berpadu untuk KDE dan desktop lainnya.
Serge Stroobandt
1
@ on4aa Ini echo ${DESKTOP_SESSION} kde-plasma-safeuntuk KDE saya. Kenapa "aman" ...
Hauke ​​Laging
Apakah ada pengguna Linux Mint Mate / Cinnamon di sini? E17, LXDE, dll. Juga diterima ...
Serge Stroobandt
1

Jika variabel lingkungan XDG_CURRENT_DESKTOPtersedia, itu akan memberi tahu Anda.

# echo $XDG_CURRENT_DESKTOP
KDE
Matthew Cline
sumber
1
Tidak mengherankan, tetapi hanya orang lain yang menyadari bahwa melewati T&J ini: tidak ada di dalam GNOME DE.
slm
Memang, dengan penekanan pada "jika ada". Lihat juga jawaban Askubuntu ini .
Serge Stroobandt
1

Anda bisa mencari Xorgproses yang sedang berjalan . Induk dari ini adalah manajer tampilan Anda. Keturunannya harus memberikan indikasi lingkungan desktop apa yang sedang berjalan. Di sistem saya, manajer tampilan mengeksekusi sendiri (dengan parameter yang berbeda). Ini kemudian memunculkan x-session-manageryang disinkronkan denganxfce4-session . Ini mungkin cukup, tetapi semua anak-anak ini terkait dengan lingkungan desktop saya. Menemukan mereka melalui pohon proses harus menjadi cara terbaik untuk mengecualikan elemen dari sistem jendela lain yang dimulai oleh berbagai program (atau mungkin dengan sengaja).

Pikiran pertama saya adalah bahwa akan lebih baik untuk mencari window manager yang terkait dengan lingkungan desktop Anda, tetapi seringkali yang berbeda dapat dikonfigurasi untuk dijalankan (misalnya xmonaddi Gnome) jadi ini tidak kuat. Yang terbaik untuk dicari mungkin adalah yang mengelola desktop aktual, mis. xfdesktopAtau elemen apa pun dari lingkungan desktop yang Anda perlukan agar skrip Anda berfungsi :)

Contoh

Berikut ini adalah contoh menggunakan procps-ng ( -Cdan --ppidbukan POSIX). Ini mengasumsikan hanya satu contoh dari Xorg.

Ini hanyalah contoh yang berfungsi untuk desktop xfce. Contoh kerja penuh memerlukan penyelidikan dalam proses yang digunakan setiap sistem desktop, seperti halnya sebagian besar solusi lain memerlukan penyelidikan tentang bagaimana variabel lingkungan diatur dalam berbagai sistem desktop lainnya.

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
sumber
Ini kembali unknowndi Ubuntu.
Serge Stroobandt
@ on4aa, itu tidak dimaksudkan sebagai solusi lengkap. Ini seharusnya menjadi contoh yang berfungsi untuk desktop xfce. Contoh yang berfungsi penuh membutuhkan penyelidikan dalam proses yang digunakan setiap sistem desktop. Saya pikir itu sudah jelas dari membaca kode.
Graeme
@Gameame Anda benar; Saya agak terlalu cepat dan mengabaikan another_desktophasil yang belum selesai .
Serge Stroobandt
1

Dari semua percobaan yang dilaporkan dalam banyak komentar, saya pikir itu tugas saya sebagai OP untuk menghasilkan jawaban konsensus. (Yakinlah, saya akan dengan senang hati meninjau jawaban ini seandainya data kontras tersedia.)

Untuk saat ini, tampaknya yang terbaik adalah mengambil pimpinan kita dari $XDG_CURRENT_DESKTOPsaat variabel ini didefinisikan. Jika tidak, $XDG_DATA_DIRSdapat memberikan informasi yang diinginkan, lebih dari huruf pertama ${DESKTOP_SESSION:0:1}.

Serge Stroobandt
sumber
Saya tidak punya XDG_CURRENT_DESKTOP. Saya pikir masalah utama dengan ini adalah variabel yang ditetapkan oleh manajer tampilan daripada lingkungan desktop dan ada beberapa ketidakkonsistenan. Ketika saya memilih sesi default (xfce) dengan lightdm echo $DESKTOP_SESSIONmemberikan lightdm-xsessionyang merupakan gabungan dari lightdmdan x-session-manager, proses yang digunakan untuk memulai desktop saya (disinkronkan ke xfce4-session). Saya membayangkan menginstal dengan sesi default yang berbeda hanya akan menggunakan symlink yang berbeda dan menghasilkan yang samaDESKTOP_SESSION
Graeme
Khususnya, jika saya secara khusus memilih XFCE atau Gnome dari manajer tampilan, DESKTOP_SESSIONakan benar-benar mengatakan xfceataugnome
Graeme
1
Solusi ini masih condong ke arah distro berbasis Debian. Tak satu pun dari metode yang dibahas bekerja pada distro berbasis Red Hat yang saya miliki aksesnya (Fedora, CentOS, dll.).
slm
1

Ini berfungsi baik pada Ubuntu 18.10 (kosmik) [tipe lxqt] dan Mint 19 (tara) [tipe kayu manis]:

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

Tangkap hasilnya menjadi variabel, dan jalankan kode yang diperlukan lebih lanjut melalui logika analitik yang mampu (case stmt, if / then) yang mencakup setiap / semua jenis yang dikenali dari sana; dan / atau berfungsi dengan anggun ketika tipe yang tidak dikenal digunakan.

odoncaoa
sumber
Bekerja juga dengan Xubuntu LTS 18.04.
Serge Stroobandt