ฉันจะรับรายการแอพพลิเคชั่นที่รันอยู่โดยใช้บรรทัดคำสั่งได้อย่างไร


8

ฉันต้องการแสดงรายการเฉพาะแอปพลิเคชันที่ทำงานเช่น: Firefox, gedit, Nautilus และอื่น ๆ โดยใช้บรรทัดคำสั่ง

หมายเหตุ: ฉันไม่ต้องการแสดงรายการกระบวนการทำงานทั้งหมดเฉพาะแอปพลิเคชันที่ทำงานอยู่ (พูด GUI ที่เรียกใช้ด้วยตนเอง)


2
"เฉพาะรายการแอปพลิเคชันที่ใช้งาน" คุณหมายถึงอะไร แอปพลิเคชันทั้งหมด (เรียกอีกอย่างว่ากระบวนการ) กำลังทำงานอยู่ คุณหมายถึงเฉพาะหน้าต่างที่เปิดเช่น 'firefox, เอาใจใส่และ Thunderbird' หรือกระบวนการทั้งหมดที่ผู้ใช้ของคุณเริ่มต้นเช่น 'unity, compiz, gnome-terminal, apt-get'?
Braiam

คำตอบ:


9

การรวมกันของwmctrlและxprop มีความเป็นไปได้มากมาย

ตัวอย่างที่ 1:

running_gui_apps() {

    # loop through all open windows (ids)
    for win_id in $( wmctrl -l | cut -d' ' -f1 ); do 

        # test if window is a normal window
        if  $( xprop -id $win_id _NET_WM_WINDOW_TYPE | grep -q _NET_WM_WINDOW_TYPE_NORMAL ) ; then 

            echo "$( xprop -id $win_id WM_CLASS | cut -d" " -f4- )"", window id: $win_id"

        fi

    done
}

ผลลัพธ์อาจมีลักษณะเช่นนี้:

"Firefox", window id: 0x032000a9
"Gnome-terminal", window id: 0x03a0000c
"Thunar", window id: 0x03600004
"Geany", window id: 0x03c00003
"Thunar", window id: 0x0360223e
"Mousepad", window id: 0x02c00003
"Mousepad", window id: 0x02c00248
"Xfce4-terminal", window id: 0x03e00004

ตัวอย่างที่ 2:

running_gui_apps() {
    applications=()

    # loop through all open windows (ids)
    for win_id in $( wmctrl -l | cut -d' ' -f1 ); do 

        # test if window is a normal window
        if  $( xprop -id $win_id _NET_WM_WINDOW_TYPE | grep -q _NET_WM_WINDOW_TYPE_NORMAL ) ; then 

            # filter application name and remove double-quote at beginning and end
            appname=$( xprop -id $win_id WM_CLASS | cut -d" " -f4 )
            appname=${appname#?}
            appname=${appname%?}

            # add to result list
            applications+=( "$appname" ) 

        fi

    done

    # sort result list and remove duplicates  
    readarray -t applications < <(printf '%s\0' "${applications[@]}" | sort -z | xargs -0n1 | uniq)

    printf -- '%s\n' "${applications[@]}" 
}

ตัวอย่างผลลัพธ์:

Firefox
Geany
Gnome-terminal
Mousepad
Thunar
Xfce4-terminal

คุณสามารถเพิ่มฟังก์ชั่นของคุณ~/.bashrcหรือเรียกใช้จากไฟล์สคริปต์


โหวตขึ้นเนื่องจากสองเหตุผล: (1) จริง ๆ แล้วมันตอบคำถาม; และที่สำคัญที่สุดคือ (2) ไม่พยายามทำให้คำถามมีความซับซ้อนด้วยข้อมูลเพิ่มเติมที่ไม่ได้อยู่ในขอบเขตของคำถามอย่างชัดเจน - ข้อมูลประเภทนี้ทำให้ผู้ใช้สับสนมากกว่าผู้ใช้ (เรา) เข้าใจและแก้ไขปัญหา
Almir Campos

2

บทนำ

พลังของxdotoolและwmctrlออกมาเมื่อคุณต้องการจัดการกับหน้าต่างเช่นการย้ายหรือปรับขนาด อย่างไรก็ตามฉันเชื่อมั่นอย่างยิ่งว่าเพื่อจุดประสงค์ในการแสดงรายการโปรแกรมและข้อมูลเกี่ยวกับพวกเขาเท่านั้นxpropและqdbusเป็นเครื่องมือที่เพียงพอและติดตั้งxdotoolและwmctrlหากผู้ใช้ไม่ต้องการสิ่งเหล่านี้สำหรับการใช้งานเพิ่มเติม - เป็นงานที่ไม่มีจุดมุ่งหมาย ในคำตอบนี้ผมอยากจะนำเสนอสองโซลูชั่นสคริปต์ด้วยและxpropqdbus

หมายเหตุว่าผมไม่ได้หมายความว่าผิดหรือxdotool wmctrlฉันใช้มันอย่างกว้างขวาง แต่ก็พบว่ามันทรงพลังกว่าเมื่อรวมกับเครื่องมืออื่น ๆ นี่เป็นเพียงตัวอย่างเล็ก ๆ น้อย ๆ ที่ฉันได้ใช้:

Xprop

ซอลเบลโลว์ร้องใช้ xprop เพียงเพื่อแยกรายชื่อของหน้าต่างที่ใช้งานอยู่กรองหน้าต่างที่แท้จริงเท่านั้น (ไม่ใช่ประเภทแท่นดูดเป็น Unity Launcher หรือ Unity Panel) และแสดงข้อมูล:

การสาธิต:

$ bash xprop_windows.sh                                                        
XID TYPE    TITLE
--------------------------------

56623112| "x-terminal-emulator", "X-terminal-emulator"| "sakura"

81789126| "Navigator", "Firefox"| "Restore Session - Mozilla Firefox"

82002372| "Navigator", "Firefox"| "gui - How do I get a list of running applications by using the command line? - Ask Ubuntu - Mozilla Firefox"

33554444| "gnome-terminal", "Gnome-terminal"| "\"Terminal\""

33554486| "gnome-terminal", "Gnome-terminal"| "\"Terminal\""

แหล่งสคริปต์:

get_hex_xids()
{
xprop -root -notype _NET_CLIENT_LIST | \
     awk 'BEGIN{printf "ibase=16"}\
     {gsub(/\,/," ");for(i=1;i<=NF;i++) \
     if ($i~/0x/) printf ";%s",substr(toupper($i),3)   }'  
}

convert_hex2dec()
{
  HEXIDS=$(get_hex_xids)
  echo $HEXIDS | bc
}

print_header()
{
  printf "%s\t%s\t%s\n" "XID" "TYPE" "TITLE"
  printf "%s\n" "--------------------------------"
}

list_info()
{
  convert_hex2dec | while read line;
  do
  TYPE=$( xprop -id $line _NET_WM_WINDOW_TYPE | awk -F '=' '{print $2}'   )
  if [ $TYPE != "_NET_WM_WINDOW_TYPE_NORMAL"   ]; then
     continue
  fi
  CLASS=$(xprop -id $line WM_CLASS | awk -F '=' '{print $2}' )
  NAME=$( xprop -id $line _NET_WM_NAME | awk -F '=' '{print $2}'   )
  printf "\n%s|%s|%s\n" "$line" "$CLASS" "$NAME"

  done
}
print_header
list_info

Qdbus

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

วิ่งตัวอย่าง:

$ bash ~/bin/qdbus_windows.sh                                                  
Name: Terminal
Active :false
Children:
33554486|false|""Terminal""
33554444|false|""Terminal""
--------------
Name: Firefox Web Browser
Active :false
Children:
82002372|false|"gui - How do I get a list of running applications by using the command line? - Ask Ubuntu - Mozilla Firefox"
81789126|false|"Restore Session - Mozilla Firefox"
--------------
Name: MY CUSTOM TERMINAL
Active :true
Children:
56623112|true|"sakura"
--------------

รหัสตัวเอง:

#!/bin/bash

get_window_paths()
{
  qdbus org.ayatana.bamf  /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.WindowPaths
}

get_running_apps()
{
  qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.RunningApplications
}

list_children()
{
 qdbus org.ayatana.bamf "$1"  org.ayatana.bamf.view.Children
}

window_info()
{
for window in "$@" ; do
 XID=${window##*/}
 TYPE=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.window.WindowType)                                         
 NAME="$(qdbus org.ayatana.bamf $window org.ayatana.bamf.view.Name)"
 ACTIVE=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.view.IsActive)
 MONITOR=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.window.Monitor)
# printf "%s|%s|%s|%s\n" $TYPE $MONITOR $ACTIVE "$NAME" 
 printf "%s|%s|\"%s\"\n" $XID $ACTIVE "$NAME" 
done
}

window_paths=( $( get_window_paths | tr '\n' ' ') )
apps_list=( $( get_running_apps | tr '\n' ' ' ) )

for app in ${apps_list[@]} ; do
#echo $app
  printf "Name: "
  qdbus org.ayatana.bamf $app org.ayatana.bamf.view.Name
  printf "Active :"
  qdbus org.ayatana.bamf $app org.ayatana.bamf.view.IsActive
  printf "Children:\n"
#  list_children $app
  windows=( $( list_children $app | tr '\n' ' ' ) )
  window_info "${windows[@]}"
  printf "%s\n"  "--------------"
done

คำสั่งที่เรียบง่ายขึ้นเล็กน้อย แต่ต้องการกรองเอาท์พุทโดยใช้หน้าต่างสแต็กอินเทอร์เฟซ dbus ของ Unity นี่คือฟังก์ชั่นที่ฉันมีในตัวฉัน.mkshrc

window_stack()
{
  qdbus --literal com.canonical.Unity.WindowStack  
        /com/canonical/Unity/WindowStack  \
        com.canonical.Unity.WindowStack.GetWindowStack | \
  awk -F '{' '{gsub(/\}|\]|,/,"");gsub(/\[/,"\n");print $2}' | \
  awk '!/compiz/&&!/^$/ && $4!="\""$3"\""  { L[n++] = $0 }\
       END { while(n--) print L[n] }'
}

วิ่งตัวอย่าง:

$ window_stack
Argument: (usbu) 56623112 "x-terminal-emulator" true 0 
Argument: (usbu) 82002372 "firefox" false 0 
Argument: (usbu) 81789126 "firefox" false 0 
Argument: (usbu) 33554486 "gnome-terminal" false 0 
Argument: (usbu) 33554444 "gnome-terminal" false 0

ตัวอย่างของการใช้ qdbus:


1

wmctrl -lอาจเป็นสิ่งที่คุณต้องการ ก่อนติดตั้ง

sudo apt-get install wmctrl

นอกจากนี้คุณยังสามารถรวมเข้ากับรายการการตรวจสอบระบบโดยค่าเริ่มต้นจะแสดง "กระบวนการของฉันทั้งหมด" ซึ่งหมายถึงกระบวนการทั้งหมดที่เป็นของคุณในฐานะผู้ใช้

ในการมีชื่อแอปพลิเคชันเท่านั้นให้รัน:

แก้ไข:

wmctrl -l|awk '{$3=""; $2=""; $1="";  print $0}'

OP ต้องการรับชื่อแอปพลิเคชันเท่านั้น เป็นไปได้ไหม
Avinash Raj

ไม่ฉันเปิดเบราว์เซอร์ Firefox คำสั่งของคุณแสดง0x03c000b3 0 avinash-Lenovo-IdeaPad-Z500 How list of running applications by command? - Ask Ubuntu - Mozilla Firefoxรวมทั้งบรรทัดพิเศษบางอย่างเกี่ยวกับเดสก์ท็อปฮัด ฯลฯ
Avinash Raj

@AvinashRaj: ขอโทษฉันกำลังทำงานกับมันฉันจะเพิ่มเร็วฉบับขอบคุณสำหรับความสนใจของคุณ
Ruslan Gerasimov

@AvinashRaj นี่คือการเพิ่มwmctrl -l|awk '{out=""; for(i=2;i<=NF;i++){out=$out" "$i}; print $out}'จะเพิ่มในคำตอบของฉัน ขอบคุณสำหรับการชี้ให้เห็น
Ruslan Gerasimov

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