วิธีการตรวจสอบสภาพแวดล้อมเดสก์ทอปในสคริปต์ทุบตี?


24

ฉันกำลังเขียนbashสคริปต์ที่ต้องรู้สภาพแวดล้อมเดสก์ท็อป (XFCE, Unity, KDE, LXDE, Mate, Cinnamon, GNOME2, GNOME3, ... ) กำลังทำงานอยู่

ฉันจะรับข้อมูลนั้นได้อย่างไร


1
นั่นเป็นเรื่องยากเพราะแม้ว่าคุณจะอยู่ในเซสชั่น GNOME และเพิ่งเริ่มโปรแกรมหนึ่งของ KDE เช่น kwrite โครงสร้างพื้นฐาน KDE ทั้งหมดเช่น KDE daemon และ kdeinit จะทำงานอยู่
Thorsten Staerk

3
คุณสวยมากไม่สามารถทำได้ไม่น่าเชื่อถือ ทำไมคุณต้องรู้ รูปลักษณ์นี้เช่นปัญหา XY
Gilles 'หยุดชั่วร้าย'

@Gilles คำถามที่ดี ฉันกำลังเขียนสคริปต์พิเศษสำหรับxplanetและต้องการรีเฟรชพื้นหลังเดสก์ท็อปโดยอัตโนมัติด้วยคำสั่งเฉพาะสำหรับสภาพแวดล้อมเดสก์ท็อป หากคุณต้องการโพสต์คำตอบสำหรับปัญหานั้นโปรดไปที่ลิงก์
Serge Stroobandt

คำตอบ:


11

ปัญหาหลักของการตรวจสอบDESKTOP_SESSIONคือตั้งค่าโดยตัวจัดการการแสดงผลมากกว่าเซสชันเดสก์ท็อปและขึ้นอยู่กับความไม่สอดคล้องกัน สำหรับlightdmใน Debian /usr/share/xsessions/ค่ามาจากชื่อของไฟล์ภายใต้ DESKTOP_SESSIONแสดงถึงสภาพแวดล้อมเดสก์ท็อปหากมีการเลือกเฉพาะเมื่อเข้าสู่ระบบอย่างไรก็ตามlightdm-xsessionจะใช้เซสชันเริ่มต้นเสมอ

GDMSESSIONเป็นอีกตัวเลือกหนึ่ง แต่ดูเหมือนว่าจะมีสถานการณ์ที่คล้ายคลึงกัน (เป็นค่าเดียวDESKTOP_SESSIONกับฉัน)

XDG_CURRENT_DESKTOPดูเหมือนจะเป็นทางเลือกที่ดี แต่ปัจจุบันไม่ได้อยู่ในมาตรฐาน XDGและไม่ได้นำไปใช้เสมอ ดูที่นี่สำหรับการสนทนานี้ คำตอบนี้แสดงค่าของ distros / เดสก์ท็อปที่แตกต่างกันฉันยังสามารถยืนยันได้ว่า XFCE ไม่สามารถใช้งานได้ในขณะนี้

ทางเลือกที่เหมาะสมสำหรับการไม่ได้ที่มีอยู่จะไปลองXDG_CURRENT_DESKTOP XDG_DATA_DIRSหากมีการติดตั้งไฟล์ข้อมูลสำหรับสภาพแวดล้อมเดสก์ท็อปในไดเรกทอรีที่มีชื่อแนวทางนี้ควรใช้งานได้ หวังว่านี่จะเป็นกรณีสำหรับ distros / เดสก์ท็อปทั้งหมด!

การทดสอบ (พร้อม grep GNU) ต่อไปนี้สำหรับ 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"

ฉันชอบสิ่งนี้. จากภาพรวมนี้จะมีปัญหากับ Cinnamon เท่านั้น อย่างไรก็ตามสิ่งนี้อาจแก้ไขได้ในที่สุดโดยการเปิดรายงานข้อบกพร่องด้วย Linux Mint
Serge Stroobandt

@ on4aa MATE ไม่ได้อยู่ในรายการ แต่มีแนวโน้มที่จะมีปัญหาเดียวกัน apt-fileเป็นเครื่องมือที่ดีในการดูว่าเดสก์ท็อปต่างๆ
แกรม

1
วิธีการแก้ปัญหานี้ยังคงเอนตัวไปสู่ ​​Distros ที่ใช้ Debian ไม่มีวิธีการใดที่พูดถึงการทำงานกับเครื่อง distros ใด ๆ ของ Red Hat ที่ฉันสามารถเข้าถึงได้ (Fedora, CentOS, ฯลฯ )
slm

@slm น่าสนใจไม่มีXDG_DATA_DIRSอยู่จริงหรือว่ามันไม่มีประโยชน์อะไรเลย?
แกรม

1
@slm จริงมากฉันคิดว่า OP น่าจะพยายามทำสิ่งที่เขาต้องการสำหรับเดสก์ท็อปแต่ละตัวใน||สไตล์ ยังมีการถามคำถามนี้กับไซต์ SE อื่น ๆ ฉันคิดว่าเรามีคำตอบที่ดีที่สุด
แกรม

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ทำให้ฉันกังวลใจเนื่องจากมีแนวโน้มที่จะมุ่งเน้นไปที่ DE เท่านั้นโดยใช้ GDM หรือ DE จาก GNOME GDM = ตัวจัดการหน้าจอของ GNOME
slm

1
@ on4aa DESKTOP_SESSIONบน xfce
แกรม

1
บน xfce, DESKTOP_SESSION ของฉันคือdefault(มิ้นต์ 15)
glenn jackman

1
เดเบียนก็แสดงdefaultสิ่งนี้เช่นกัน การติดตั้งเริ่มต้นของ GNOME 3
slm

1
$DESKTOP_SESSIONแสดงdefaultให้ KDE ภายใต้ Fedora 20
Matthew Cline

5

คุณสามารถใช้สคริปต์ทุบตีนี้ สามารถตรวจจับชื่อและรุ่นของสภาพแวดล้อมเดสก์ทอป

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

ฉันขโมยความคิดของคุณเพื่อตรวจสอบ Xfce ในสคริปต์ของฉัน:ps -e | grep -E '^.* xfce4-session$' > /dev/null (($? == 0)) && ...
Colin Keenan

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
ภูมิพลอดุลยเดช

1

ที่อาจขึ้นอยู่กับสถานการณ์ หากคุณรู้ว่าตัวจัดการการแสดงผลใดที่ใช้อาจเป็นไปได้ว่าข้อมูลนี้ทำให้ข้อมูลนี้อยู่ในตัวแปรสภาพแวดล้อม

หากไม่เป็นเช่นนั้นฉันคิดว่าคุณต้องตรวจสอบ DE ทุกครั้งที่คุณต้องการระบุตัวตน พวกเขาทั้งหมดควรแนะนำตัวแปรสภาพแวดล้อมของตนเอง


ฉันสงสัยว่าecho ${DESKTOP_SESSION:0:1}จะทำเคล็ดลับหรือไม่ เท่าที่ฉันทดสอบได้มันจะคืนกลับมาuให้ Unity และxXFCE หวังว่าชาวบ้านบางคนจะเข้าร่วมกับ KDE และเดสก์ท็อปอื่น ๆ
Serge Stroobandt

1
@ on4aa echo ${DESKTOP_SESSION} kde-plasma-safeสำหรับ KDE ของฉัน ทำไม "ปลอดภัย" ...
Hauke ​​Laging

มีผู้ใช้ Linux Mint Mate / Cinnamon ที่นี่บ้างไหม? E17, LXDE และอื่น ๆ ยินดีต้อนรับ ...
Serge Stroobandt

1

หากตัวแปรสภาพแวดล้อมXDG_CURRENT_DESKTOPพร้อมใช้งานควรบอกคุณ

# echo $XDG_CURRENT_DESKTOP
KDE

1
ไม่ใช่เรื่องแปลก แต่ก็มีคนอื่นรู้ว่าการผ่านคำถามและคำตอบนี้: ไม่มีอยู่ใน GNOME DE
slm

แน่นอนโดยเน้นที่ "ถ้ามี" ดูคำตอบ Askubuntuนี้ด้วย
Serge Stroobandt

1

คุณสามารถมองหาXorgกระบวนการทำงานได้ พาเรนต์ของสิ่งนี้ควรเป็นตัวจัดการการแสดงผลของคุณ ลูกหลานของมันควรระบุสิ่งที่สภาพแวดล้อมเดสก์ทอปกำลังทำงานอยู่ ในระบบของฉันตัวจัดการการแสดงผลดำเนินการเอง (ด้วยพารามิเตอร์ที่ต่างกัน) นี้แล้ว spawns x-session-managerซึ่งเป็น symlinked 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

@ on4aa นั่นไม่ได้หมายความว่าจะเป็นทางออกที่สมบูรณ์ นี่ควรจะเป็นตัวอย่างที่เหมาะกับเดสก์ทอป xfce ตัวอย่างการทำงานแบบสมบูรณ์ต้องการการตรวจสอบกระบวนการที่ระบบเดสก์ท็อปแต่ละเครื่องใช้ ฉันคิดว่าคงชัดเจนจากการอ่านรหัส
แกรม

@ เกมคุณถูกต้อง; ฉันค่อนข้างเร็วเกินไปและมองข้ามanother_desktopผลลัพธ์ที่ยังไม่เสร็จ
Serge Stroobandt

1

จากการทดลองทั้งหมดที่รายงานในความคิดเห็นจำนวนมากฉันคิดว่ามันเป็นหน้าที่ของฉันในฐานะ OP เพื่อหาคำตอบฉันทามติ (มั่นใจได้ฉันยินดีที่จะตรวจสอบคำตอบนี้หากมีข้อมูลที่ตัดกัน)

สำหรับตอนนี้ดูเหมือนจะดีที่สุดที่จะนำของเราจาก$XDG_CURRENT_DESKTOPเมื่อตัวแปรนี้ถูกกำหนดไว้ ถ้าไม่อาจให้ข้อมูลที่ต้องการได้มากไปกว่าตัวอักษรตัวแรกของ$XDG_DATA_DIRS${DESKTOP_SESSION:0:1}


XDG_CURRENT_DESKTOPฉันไม่มี ฉันคิดว่าปัญหาหลักของสิ่งเหล่านี้คือตัวแปรที่พวกเขาตั้งค่าโดยตัวจัดการหน้าจอมากกว่าสภาพแวดล้อมเดสก์ท็อปและดังนั้นจึงมีความไม่สอดคล้องกันบางอย่าง เมื่อฉันเลือกเซสชันเริ่มต้น (xfce) ด้วย lightdm echo $DESKTOP_SESSIONให้lightdm-xsessionซึ่งเป็นการรวมกันของlightdmและx-session-managerกระบวนการที่ใช้ในการเริ่มต้นเดสก์ทอปของฉัน (symlinked to xfce4-session) ฉันจินตนาการว่าการติดตั้งด้วยเซสชันเริ่มต้นที่แตกต่างกันจะใช้ symlink ที่แตกต่างกันและให้ผลเหมือนกันDESKTOP_SESSION
Graeme

โดยเฉพาะอย่างยิ่งถ้าฉันเลือก XFCE หรือ Gnome จากตัวจัดการการแสดงผลโดยเฉพาะอย่างยิ่งDESKTOP_SESSIONจริง ๆ จะพูดxfceหรือgnome
Graeme

1
วิธีการแก้ปัญหานี้ยังคงเอนตัวไปสู่ ​​Distros ที่ใช้ Debian ไม่มีวิธีการใดที่พูดถึงการทำงานกับเครื่อง distros ใด ๆ ของ Red Hat ที่ฉันสามารถเข้าถึงได้ (Fedora, CentOS, ฯลฯ )
slm

1

ใช้ได้กับทั้ง Ubuntu 18.10 (จักรวาล) [ประเภท lxqt] และเหรียญกษาปณ์ 19 (ธารา) [ประเภทซินนามอน]:

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

จับผลลัพธ์ลงในตัวแปรและรันโค้ดที่จำเป็นเพิ่มเติมผ่านตรรกะการวิเคราะห์ที่มีความสามารถ (case stmt, if / then) ซึ่งรวมถึง / ชนิดที่รู้จักใด ๆ จากที่นั่น; และ / หรือฟังก์ชั่นอย่างสง่างามเมื่อมีการใช้ประเภทที่ไม่รู้จัก


ใช้ได้กับ Xubuntu LTS 18.04
Serge Stroobandt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.