Я хочу перечислить только запущенные приложения, такие как: Firefox, gedit, Nautilus и т. Д. С помощью командной строки.
Примечание: я не хочу перечислять все запущенные процессы, только приложения, которые работают (скажем, GUI, запущенные вручную).
Комбинация 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
или запустить ее из файла сценария.
wmctrl -l
может быть тем, что вам нужно. Сначала установите его
sudo apt-get install wmctrl
Вы также можете объединить его со списком системного монитора, по умолчанию он показывает «Все мои процессы», что означает все процессы, принадлежащие вам как пользователю.
Чтобы иметь только имена приложений, запустите:
РЕДАКТИРОВАТЬ:
wmctrl -l|awk '{$3=""; $2=""; $1=""; print $0}'
Мощность xdotool
и wmctrl
проявляется, когда вам нужно выполнить манипуляции на окнах, например перемещение или изменение размера. Однако я твердо уверен, что только для перечисления запущенных программ и информации о них, xprop
и qdbus
являются двумя достаточными инструментами и установкой xdotool
и wmctrl
, если пользователю не нужны дополнительные функции, - это бессмысленная задача. В этом ответе я хотел бы представить два скриптовых решения с xprop
и qdbus
.
Обратите внимание, что я ни в коем случае не против xdotool
или wmctrl
. Я сам активно их использовал, но считаю, что они более эффективны в сочетании с другими инструментами. Вот лишь несколько примеров, в которых я их использовал:
Сценарий ниже использует только 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\""
Script source :
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
приведенный ниже код выполняет, по сути, ту же задачу, однако он сначала фильтрует приложения, затем перечисляет их дочерние окна и, наконец, предоставляет информацию о них.
Пример выполнения:
$ 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: