Tôi muốn liệt kê chỉ ứng dụng đang chạy như: Firefox, gedit, Nautilus, v.v. bằng cách sử dụng dòng lệnh.
Lưu ý: Tôi không muốn liệt kê tất cả quy trình đang chạy, chỉ các ứng dụng đang chạy (giả sử GUI được khởi chạy thủ công).
Tôi muốn liệt kê chỉ ứng dụng đang chạy như: Firefox, gedit, Nautilus, v.v. bằng cách sử dụng dòng lệnh.
Lưu ý: Tôi không muốn liệt kê tất cả quy trình đang chạy, chỉ các ứng dụng đang chạy (giả sử GUI được khởi chạy thủ công).
Câu trả lời:
Một sự kết hợp wmctrl
và xprop
cung cấp nhiều khả năng.
Ví dụ 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
}
Đầu ra có thể trông giống như trong trường hợp này như sau:
"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
Ví dụ 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[@]}"
}
Ví dụ đầu ra:
Firefox
Geany
Gnome-terminal
Mousepad
Thunar
Xfce4-terminal
Bạn có thể thêm chức năng vào ~/.bashrc
hoặc chạy nó từ tệp tập lệnh.
Sức mạnh của xdotool
và wmctrl
đi ra khi bạn cần thực hiện thao tác trên các cửa sổ, chẳng hạn như di chuyển hoặc thay đổi kích thước. Tuy nhiên, tôi tin tưởng mạnh mẽ rằng với mục đích chỉ liệt kê các chương trình và thông tin đang chạy, xprop
và qdbus
là hai công cụ và cài đặt đầy đủ xdotool
và wmctrl
trừ khi người dùng muốn những thứ đó cho chức năng bổ sung - là một nhiệm vụ không mục đích. Trong câu trả lời này, tôi muốn trình bày hai giải pháp kịch bản với xprop
và qdbus
.
Lưu ý rằng tôi không có nghĩa là chống lại xdotool
hoặc wmctrl
. Bản thân tôi đã sử dụng chúng rộng rãi, nhưng tôi thấy chúng mạnh hơn khi kết hợp với các công cụ khác. Đây chỉ là một vài ví dụ mà tôi đã sử dụng chúng:
Tập lệnh dưới đây chỉ sử dụng xprop để trích xuất danh sách các cửa sổ đang hoạt động, chỉ lọc ra các cửa sổ thật (không phải kiểu dock như Unity Launcher hoặc Unity Panel) và hiển thị thông tin của chúng:
Bản giới thiệu:
$ 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\""
Nguồn kịch bản :
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
Mã dưới đây thực hiện cùng một nhiệm vụ, tuy nhiên, nó lọc các ứng dụng trước, sau đó liệt kê các cửa sổ con của nó và cuối cùng cung cấp thông tin về chúng.
Chạy mẫu:
$ 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"
--------------
Mã chính nó:
#!/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
Lệnh đơn giản hơn một chút nhưng yêu cầu lọc ra đầu ra sử dụng giao diện dbus stack stack của Unity. Đây thực chất là một chức năng tôi có trong.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] }'
}
Chạy mẫu:
$ 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
Ví dụ về việc sử dụng qdbus:
wmctrl -l
có thể là một điều bạn muốn. Đầu tiên cài đặt nó
sudo apt-get install wmctrl
Bạn cũng có thể kết hợp nó với danh sách của System Monitor, theo mặc định, nó hiển thị "Tất cả các quy trình của tôi" có nghĩa là tất cả các quy trình thuộc về bạn với tư cách là người dùng.
Để chỉ có tên của các ứng dụng, hãy chạy:
BIÊN TẬP:
wmctrl -l|awk '{$3=""; $2=""; $1=""; print $0}'
0x03c000b3 0 avinash-Lenovo-IdeaPad-Z500 How list of running applications by command? - Ask Ubuntu - Mozilla Firefox
cộng với một số dòng bổ sung về Desktop, Hud, v.v.
wmctrl -l|awk '{out=""; for(i=2;i<=NF;i++){out=$out" "$i}; print $out}'
, sẽ thêm vào câu trả lời của tôi. Cảm ơn bạn đã chỉ ra.