lista - ¿Hay un comando de Linux para determinar los identificadores de ventana asociados con un identificador de proceso determinado?
lista completa de comandos linux pdf (4)
Los permisos de xwininfo y xprop para recuperar lo que quieres, pero es un poco complicado.
xwininfo permite recuperar todas las ventanas conocidas y xprop para consultar a X acerca de una ID de ventana única para su parámetro _NET_WM_PID.
Hasta ahora, una forma estrafalaria de hacerlo sería:
#!/bin/sh
findpid=$1
known_windows=$(xwininfo -root -children|sed -e ''s/^ *//''|grep -E "^0x"|awk ''{ print $1 }'')
for id in ${known_windows}
do
xp=$(xprop -id $id _NET_WM_PID)
if test $? -eq 0; then
pid=$(xprop -id $id _NET_WM_PID|cut -d''='' -f2|tr -d '' '')
if test "x${pid}" = x${findpid}
then
echo "Windows Id: $id"
fi
fi
done
Resultado:
mycroft:~ $ ./find_windows.sh 1919
Windows Id: 0x1800748
Windows Id: 0x181b221
Windows Id: 0x1803ad5
Windows Id: 0x181f681
Windows Id: 0x181f658
Windows Id: 0x180006d
Windows Id: 0x1800003
Windows Id: 0x1800001
Windows Id: 0x180001e
Como verá, un solo proceso puede tener un cierto número de ventanas conocidas, incluso si solo ve una en su pantalla.
Tal vez debería obtener estas fuentes de herramientas para hacer lo que quiere.
Dado un proceso iD de XX, me gustaría tener una lista de identificadores de ventanas donde _NET_WM_PID = XX. Aún mejor sería el identificador de ventana activo más antiguo si es posible.
Soy muy nuevo en Linux, pero lo que intento hacer es crear un script que tome una línea de comando y ver si hay una ventana abierta que pertenece a un proceso invocado con esa misma línea de comando. Si es así, simplemente establezca el foco en esa ventana, de lo contrario, ejecute la línea de comandos para iniciar un nuevo proceso. Mi intención es usar esto en mi escritorio ubuntu, donde engancharé este script en mis comandos de gesto de mouse easystroke, para que, por ejemplo, cada vez que hago un gesto para gmail no obtenga una nueva sesión de Gmail, solo llegar a mi ventana actual de la aplicación gmail chrome. Tal vez haya una manera mucho más fácil de abordar todo esto, pero aún no he encontrado mi camino.
Con ayuda, he descubierto cómo encontrar un PID para una línea de comando con pgrep y cómo establecer el foco en un identificador de ventana con wmctrl, pero me atasco al pasar de PID a ID de ventana.
Puedes usar:
xdotool getwindowfocus getwindowname
(Como es: no es necesario reemplazar esos nombres que suenan bien con nada).
También puedes buscar PIDs con wmctrl , y creo que es una mejor manera de hacerlo. xwininfo devolverá todo tipo de entidades que parecen ser Windows, pero no las encontrará realmente en su escritorio.
Si hace man wmctrl , encontrará que wmctrl -l enumera todas las ventanas que son realmente visibles en su escritorio con (más importante) sus identificaciones de ventanas y títulos . -p agrega PID y -x agregará clases de ventana .
Como dice el manual (RTFM, ¿verdad?: D), wmctrl también puede buscar a través de algunos de estos y activar una ventana que coincida con la búsqueda. Sin embargo, no tengo idea de qué determina cuál de todas las coincidencias posibles se devolverá. Por otro lado, puede usar la función de lista provista para escribir un contenedor que haga la búsqueda mejor y posiblemente en función de otras propiedades (como la marca de tiempo del último acceso a la ventana) que puede obtener al consultar la ganancia provista. id a xprop, por ejemplo.
Estas líneas de código a continuación devuelven la instancia más reciente de una ventana de clase de terminal mate:
XTIME="_NET_WM_USER_TIME" #a shorter name for xprop query that shoul return timestamps
export TMPDIR=/dev/shm #save tmp files to memory to make it faster
LST=`mktemp` #tmp file to store our listing
wmctrl -lx | awk -F'' '' ''{printf("%s/t%s /t",$1,$3); for(i=5;i<=NF;i++) printf("%s",$i); printf("/n") }'' > $LST #pretty-print our listing of windows into the tmp file
#To each line of listing, prepend a timestamp acquired via an xprop call
#Use awk to find a line whose 3rd column (winclass) matches the window class "mate-terminal.Mate-terminal" and among those that do, find the one whose timestamp is the largest
while read LINE; do ID=`echo "$LINE"|cut -f 1`; TIME=`xprop -id $ID $XTIME`; TIME="${TIME/* = /}"; echo -e "$TIME/t$LINE" ; done <$LST ) | awk -v s="mate-terminal.Mate-terminal" ''$3 == s {if($1>max){max=$1;line=$0};};END{print line}''
rm $LST #delete tmp file
De todos modos, para lo que describes que estás construyendo, si yo fuera tú, averiguaría qué clase de ventanas genera tu comando deseado y luego basaré mi búsqueda en eso, en lugar de basarme en los PID. Alternativamente, podría suponer que el comando CMD posiblemente generará ventanas con un nombre de clase que incluya CMD.
Después de que haya encontrado su línea, debe usar el ID de ventana
para activar la ventana a través de wmctrl.
Espero que esto ayude.
Una nota al margen: descubrí que xdotool también puede realizar búsquedas basadas en nombres de clase y títulos de ventanas, pero es extremadamente lento . En mi computadora, este script de bash (que llama a un par de utilidades externas) es 10 veces más rápido que la alternativa compilada que es xdotool: P.
Here hay varias soluciones de administración de ventanas X11 (incluida una para este problema).
Xwininfo y xprop son buenas herramientas para obtener los ID de todas las ventanas, pero no las herramientas más fáciles para obtener el ID de la ventana principal asociada con un PID (si eso es posible con ellos). Para obtener el ID de la ventana principal, use wmctrl de la siguiente manera:
#!/usr/bin/env bash
# getwindidbypid
#
# Get the ID of a window by PID (if the process has a window).
#
# Usage:
# getwindidbypid <PID>
#
while IFS= read line; do
if [[ "${line}" =~ (0x)([0-9a-z]+)([ ][- ][0-9]+[ ])([0-9]*) ]]; then
winId="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
pid="${BASH_REMATCH[4]}"
if [[ "${pid}" -eq "${1}" ]]; then
WIND_IDS+=("${winId}")
fi
fi
done < <(wmctrl -lp)
if [ "${#WIND_IDS[@]}" -gt 0 ]; then
echo "${WIND_IDS[@]}"
fi
Ejemplo:
user ~ $ getwindidbypid 37248
0x05a00012
Esta solución imprimirá múltiples identificadores de ventana si wmctrl encuentra más de una ventana principal. Para devolver solo el primero, simplemente cambie [@]
a [0]
en echo "${WIND_IDS[@]}"
.