How do I get a list of running applications by using the command line?
Solution 1
A combination of wmctrl
and xprop
offers many possibilities.
Example 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
}
The output could look in this case similar like this:
"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
Example 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[@]}"
}
Output example:
Firefox
Geany
Gnome-terminal
Mousepad
Thunar
Xfce4-terminal
You can add the function to your ~/.bashrc
or run it from an script file.
Solution 2
Introduction
The power of xdotool
and wmctrl
comes out when you need to perform manipulation on the windows, such as moving or resizing. However, I strongly believe that for the purpose of only listing running programs and information about them, xprop
and qdbus
are two sufficient tools and installing xdotool
and wmctrl
unless the user wants those for additional functionality - is a purposeless task. In this answer I would like to present two scripting solutions with xprop
and qdbus
.
Note that I am by no means against xdotool
or wmctrl
. I've used them extensively myself , but I find them more powerful when combined with other tools. Here are just a few examples where I've used them :
Xprop
The script bellow uses only xprop to extract list of the active windows , filter out only true windows ( not dock type suck as Unity Launcher or Unity Panel ) and display their info:
Demo:
$ 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
Qdbus
The code bellow performs essentially the same task, however it filters out applications first, then lists its children windows , and finally provides info about them.
Sample run:
$ 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"
--------------
Code itself:
#!/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
A bit simpler command but requires filtering out the output uses Unity's window stack dbus interface. Here is essentially a function I have in my .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] }'
}
Sample run:
$ 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
Examples of qdbus usage:
Solution 3
wmctrl -l
could be a thing you wanted. First install it
sudo apt-get install wmctrl
You can also combine it with System Monitor's list, by default it shows "All my processes" which means all process that belong to you as a user.
To have only names of applications, run:
EDIT:
wmctrl -l|awk '{$3=""; $2=""; $1=""; print $0}'
Related videos on Youtube
Pandya
Started using Linux and StackExchange since Ubuntu 12.04 LTS. Then Upgraded to 14.04 LTS. Now I am using Debian GNU/Linux on my Laptop and PureOS on old Desktop computer. I recommend visiting the Philosophy of GNU Project As I've replaced Ubuntu with Debian GNU/Linux, Now my question(s) are became off-topic on AskUbuntu. So, I continue to Unix & Linux. The second reason for my shifting to U & L is I found U & L more interesting than AU since AU is only Ubuntu specific whereas U & L is a broad concept and in my opinion U & L deserves generic questions. (I know why SE has AU & U & L both).
Updated on September 18, 2022Comments
-
Pandya over 1 year
I want to list only running application like: Firefox, gedit, Nautilus, etc. using the command line.
Note: I don't want to list all running process, only applications which are running (say manually launched GUIs).
-
Braiam almost 10 years"only list application which is running" what do you mean? all applications (known also as processes) are running. You mean only opened windows, like 'firefox, empathy and thunderbird' or all process that your user started like 'unity, compiz, gnome-terminal, apt-get'?
-
-
Avinash Raj almost 10 yearsOP wants to get only the application name. Is this possible?
-
Ruslan Gerasimov almost 10 years@AvinashRaj this is an addition,
wmctrl -l|awk '{out=""; for(i=2;i<=NF;i++){out=$out" "$i}; print $out}'
, will add to my answer. Thank you for pointing out. -
Avinash Raj almost 10 yearssorry , won't works for me.
-
Pandya almost 10 years@RuslanGerasimov
wmctrl -l|awk '{out=""; for(i=2;i<=NF;i++){out=$out" "$i}; print $out}'
Not working and getting errorawk: program limit exceeded: maximum number of fields size=32767 FILENAME="-" FNR=1 NR=1
-
Ruslan Gerasimov almost 10 yearssorry gentlemen, I don't know how it happened, that is the correct command:
wmctrl -l|awk '{$3=""; $2=""; $1=""; print $0}'
will add at the final answer's edition -
TuKsn almost 10 yearsBut with this command you only get the title of the open windows and thats often not the name of the application...
-
Almir Campos almost 5 yearsUp-voted due two reasons: (1) it actually answered the question; and, (2), most importantly, didn't try to complicate the question with additional information that very clearly weren't in the scope of the question - these kind of information cause more confusion to the users than help them (us) to understand and solve the problem.