----
#!/usr/bin/env bash
# this script walks the tree of known X windows on the system and
# prints out those that have PIDs (process ids; see ps(1)) associated
# with them.
# usage: "$0", or "$0 windowid ..."; in the former, the windows are
# traversed from the root window; in the latter, from the designated
# window id(s).
# the output is: pid windowid name [secondary]\n...
# program we use to list windowids
LSW=lsw
# recursive part of getwinids
function rgetwinids() {
local windowid=$1 a i
echo ${windowid}
a=$(${LSW} $windowid | awk '{print $1}')
for i in $a; do
rgetwinids $i
done
}
# output the windowids that seem to be on the system.
function getwinids() {
local arg
if [[ $# -eq 0 ]] ; then
echo $(rgetwinids);
else
for arg in $*; do echo $(rgetwinids ${arg}); done
fi
}
# do some processing on grep output
function gnhelper() {
grep -w "$1" |
head -1 |
tr -d '\n' |
awk '{$1=""; $2=""; print; exit}' |
sed 's/^[[:blank:]]*"//' |
sed 's/"$//';
}
# now, get the name (and maybe surf(1) uri) of the window
function getname() {
local winid=$1 wim su
wim=$(xprop -id ${winid} | gnhelper ${pname});
if [[ ${args} == 0 ]]; then
echo ${wim}
else
su=$(xprop -id ${winid} | gnhelper ${sname});
if [[ -z $su ]]; then
echo ${wim};
else
echo "${wim} [$su]"
fi
fi
}
# how many digits might be in a PID? will give one greater (newline
# counted by wc(1))
function pidndigits() {
local i
echo $(
(for i in $(ps haxo pid); do
echo $i |
wc |
awk '{print $3}';
done) |
sort -nu |
tail -1
)
}
# get the process id of the process that "owns" a window
function getpid() {
xprop -id $1 | grep PID | awk '{print $3}';
}
# make sure ${LSW} is installed
function prereq() {
a=$(${LSW} $windowid);
if [[ $? -ge 126 ]] ; then
printf "required program ${LSW} not found; see https://suckless.org\n(or install package suckless-tools)\n" > /dev/stderr
exit 1;
fi
}
function help() {
echo "\
$(basename $0) lists all the windows open on the system, along with
their process IDs (pids), optionally ([--winid|-w]) the window ids, as
well as the name property of each window (\"WM_ICON_NAME\" is the
default property here), optionally ([-s]) a secondary property of the
window (\"_SURF_URI\" is the default) is listed after the primary
(enclosed in square brackets).
the width of the (combined) primary and secondary properties can be
set with [--cmdn|-c]; the width of the PID field set with [--pidn|-p].
"
echo
usage
}
function usage() {
if [[ ! -z $1 ]] ; then echo "invalid argument \"$1\"" > /dev/stderr; fi
echo "usage: $(basename $0)
[-s]
[--winid|-w]
[--help|-h]
[[--cmdn|-c] NUM (${DEF_argnc})]
[[--pidn|-p] NUM (${DEF_argnp})]
[--pname STRING (\"${DEF_pname}\")]
[--sname STRING (\"${DEF_sname}\")]" > /dev/stderr
exit 1;
}
function parseargs() {
local optlist="-l cmdn:,help,pidn:,pname:,sname:,winid -o c:hp:sw" optresult
# http://bahmanm.com/blogs/command-line-options-how-to-parse-in-bash-using-getopt
# of help here
DEF_pname=WM_ICON_NAME
DEF_sname=_SURF_URI
DEF_argnc=200 # digits reserved for name field
DEF_argnp=$(pidndigits) # how many digits should we reserve for pid?
DEF_args=0
DEF_argwinid=0
cn=${DEF_argnc}
pn=${DEF_argnp}
argwinid=${DEF_pwinid}
pname=${DEF_pname}
sname=${DEF_sname}
args=${DEF_args}
optresult=$(getopt ${optlist} -- "$_AT_")
if [[ $? != 0 ]]; then usage; fi
eval set -- ${optresult}
while true ; do
case "$1" in
-c|--cmdn) cn=$2; shift 2 ;;
-h|--help) help; shift ;;
-p|--pidn) pn=$2; shift 2 ;;
-s) args=1; shift ;;
-w|--winid) argwinid=true ; shift ;;
--pname) pname=$2; shift 2 ;;
--sname) sname=$2; shift 2 ;;
--) shift; desired=$*; break ;;
*) usage $1; ;; # NOTREACHED
esac
done
}
function main() {
local winid a b winidpart
parseargs $*
prereq
for winid in $(getwinids ${desired} | tr '[[:blank:]]' '\n' | sort -u | tr '\n' " "); do
a=$(getpid ${winid})
if [[ ! -z $a ]]; then
b=$(getname ${winid}) # get name string for this window
if [[ ${argwinid} ]]; then
winidpart=" ${winid} ";
else
winidpart=" ";
fi
printf "%${pn}d%s%-.${cn}s\n" $a "${winidpart}" "$b"
fi
done | sort -n -k1
}
main $*
Received on Thu Sep 07 2017 - 14:14:57 CEST
This archive was generated by hypermail 2.3.0 : Thu Sep 07 2017 - 14:24:18 CEST