xterm $WINDOWID
feature
Under xterm
environment as some other implementation, you could find this variable:
echo $WINDOWID
58720292
So for any other pid:
Shortly by using sed
:
targetpid=12345
sed -zne 's/WINDOWID=//p' /proc/$targetpid/environ
...
xdotool windowactivate $(sed -zne 's/WINDOWID=//p' /proc/$targetpid/environ)
Or in a pure bash function:
getWinFromPid () {
local pid=$1 array line
[ -z "$pid" ] || [ ! -d /proc/$pid ] && return -1
local -n result=${2:-winIDfromPid[$pid]}
mapfile -d $'\0' -t array </proc/$pid/environ
for line in "${array[@]}" ;do
[ -z "${line%WINDOWID=*}" ] &&
result=${line#*=} && return
done
}
Then
getWinFromPid 123456 myWinId
xdotool windowactivate $myWinId
For other term, like gnome-terminal
:
This is strong because we don't want pid of terminal
process, but pid of shell
using terminal. For sample:
wmctrl -lp
don't show wanted pids!
So we have to navigate in hierarchy of process
1. Get Window ID from process ID
1a. Current active terminal window
From active session himself:
SHWINID=$(xprop -root | sed -ne 's/^_NET_ACTIVE_WINDOW.*[)].*window id # //p')
This work as you type this in any active terminal console.
Then now, with xdotool
:
sleep 12; xdotool windowactivate $SHWINID
You can now switch to another window, will be back in 12 seconds.
1b. Window ID from any shell or subprocess ID
I wrote this little function:
getWinFromPid () {
local pid=$1 ttypid crtpid wid xprop ttycheck
[ -z "$pid" ] || [ ! -d /proc/$pid ] && return -1
local -n result=${2:-winIDfromPid[$pid]}
read ttycheck < <(ps ho tty $pid)
ttypid=$ttycheck
while [ "$ttypid" = "$ttycheck" ]; do
crtpid=$pid
read pid ttypid < <(ps ho ppid,tty $pid)
done
result=
while [ -z "$result" ] && read wid; do
xprop=$(xprop -id $wid)
[ "$xprop" ] && [ -z "${xprop//*_NET_WM_DESKTOP*}" ] &&
[ -z "${xprop//*_NET_WM_PID(CARDINAL) = $crtpid*}" ] && result=$wid
done < <(xwininfo -root -children -all |
sed -e '1,/children:$/d;s/^ *\(0x[0-9a-fA-F]\+\) .*/\1/p;d')
}
Then
getWinFromPid <process id> [<variable name>]
If no variable name submited, this will populate global array $winIDfromPid
with pid id as index number:
getWinFromPid 1234 winId
echo $winId
0x0100012345
getWinFromPid 1234
echo ${winIDfromPid[1234]}
0x0100012345
declare -p winIDfromPid
declare -a winIDfromPid=([1234]="0x0100012345")
Nota: this was tested with xterm
, mate-terminal
, konsole
and gnome-terminal
.
Nota2: If you already have wmctrl
installed, you could replace two last lines of function:
done < <(xwininfo -root -children -all |
sed -e '1,/children:$/d;s/^ *\(0x[0-9a-fA-F]\+\) .*/\1/p;d')
by:
done < <(wmctrl -l|sed -ne 's/^ *\(0x[0-9a-fA-F]\+\) .*/\1/p');}
function will become approx 2time faster.
2. Get process running PID from a window ID
winID=0x123456
ps --ppid $(xprop -id $winID _NET_WM_PID|sed s/.*=//) ho sid |
xargs -I{} -n1 ps --sid {} fw
or without ID, you will have to click with mouse:
ps --ppid $(xprop _NET_WM_PID|sed s/.*=//) ho sid|xargs -I{} -n1 ps --sid {} fw
Into a function
psWin() {
ps --ppid $(xprop ${1+-id} $1 _NET_WM_PID|sed s/.*=//) ho sid |
xargs -I{} -n1 ps --sid {} fw
}
Then:
psWin $SHWINID
PID TTY STAT TIME COMMAND
30529 pts/2 Ss 0:00 bash
19979 pts/2 S+ 0:00 \_ bash
19982 pts/2 S+ 0:00 \_ xargs -I{} -n1 ps --sid {} fw
19986 pts/2 R+ 0:00 \_ ps --sid 30529 fw
3. List of shell windows, with process
Finally, there is a little function for showing a list of window with process.
shWinList () {
local pids=() wids=() wtitl=() ttys=() pid ttypid wpid crtpid line title desk ttycheck
for pid in $(ps axho pid,tty| sed -ne 's/ pts.*//p') ;do # list pid / tty
wpid=$pid ttypid=
read ttycheck < <(ps ho tty $pid)
ttypid=$ttycheck
while [ "$ttypid" = "$ttycheck" ]; do
crtpid=$wpid
read wpid ttypid < <(ps ho ppid,tty $wpid)
done
[ -e /proc/$pid ] && pids[crtpid]+=$pid\ ttys[crtpid]=$ttycheck
done
while read wid; do title= pid= desk= # list wid / tty
while read line; do
[ "$line" ] && {
[ -z "${line%%_NET_WM_PID*}" ] && pid=${line##*= }
[ -z "${line%%WM_NAME*}" ] &&
title=${line#*\"} title=${title%\"*}
[ -z "${line%%_NET_WM_DESKTOP(*}" ] && desk=${line##*= } ;}
done < <(xprop -id $wid)
[ "${pids[pid]}" ] && [ "$title" ] && [ "$desk" ] &&
wtitl[16#${wid#0x}]=${title} wids[16#${wid#0x}]=${pids[pid]} \
ttys[16#${wid#0x}]=${ttys[pid]}
done < <(xwininfo -root -children -all |
sed -ne 's/^ *\(0x[0-9a-fA-F]\+\) .*/\1/p')
for xwin in ${!wids[@]} ;do out= # merge & print
printf " 0x%x %-9s %-40s " $xwin "${ttys[$xwin]}" "${wtitl[$xwin]}"
for pid in ${wids[$xwin]} ;do
mapfile -d '' cmdl < /proc/$pid/cmdline
echo -n " $pid[${cmdl[*]}]"
done ; echo
done
}
Then
shWinList
0xa600024 pts/42 user@hostloc: /tmp 14817[bash]
0x1c00024 pts/3 user@hostloc: ~ 29349[watch ps --tty pts/3 fw] 31989[bash]
0x4600024 pts/16 user@remote: ~ 14441[ssh user@remote]
0x6000024 pts/43 user@hostloc: ~ 5728[bash]