Is there a linux command to determine the window IDs associated with a given process ID?
给定XX的进程iD,我想有一个任何窗口ID的列表,其中_NET_WM_PID = XX。如果可能的话,最好的办法是最旧的仍处于活动状态的窗口ID。
我对linux还是很陌生,但是我想做的是创建一个使用命令行的脚本,并查看是否已经有一个窗口打开了,该窗口属于使用同一命令行调用的进程。如果是这样,只需将焦点设置在该窗口上,否则执行命令行以进行新的处理。我的意图是在ubuntu桌面上使用此脚本,在该桌面上,我会将这个脚本挂接到我的笔触鼠标手势命令中,这样,例如,每次我为gmail手势时,我都不会获得全新的gmail会话,转到我现有的gmail chrome应用程序窗口。也许有一个更简单的方法可以解决所有这些问题,但是我还没有找到解决方法。
在帮助下,我已经弄清楚了如何使用pgrep为命令行找到PID,以及如何使用wmctrl将焦点设置到窗口句柄,但是我一直坚持从PID到窗口ID。
xwininfo和xprop允许检索您想要的内容,但这有点棘手。
xwininfo允许检索所有已知的窗口,并且xprop可以查询_NET_WM_PID参数的有关单个窗口ID的X。
到目前为止,一种骇人听闻的方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/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 |
结果:
1 2 3 4 5 6 7 8 9 10 | 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 |
如您将看到的,即使您仅在屏幕上看到一个窗口,单个进程也可能具有一定数量的已知窗口。
也许您应该获得这些工具资源,以便做出自己想要的东西。
实际上,您也可以使用wmctrl查找PID,我认为这是一种更好的方法。 xwininfo将返回看起来像Windows的各种实体,但是您不会在桌面上真正找到它们。
如果你做男人wmctrl
,您会发现wmctrl -l列出了在桌面上实际可见的所有窗口,以及(最重要的是)它们的窗口ID和标题。 -p添加PID,-x添加窗口类。
正如手册所说(RTFM,对吗?:D),wmctrl也可以搜索其中的一些并激活与搜索匹配的窗口。但是,我不知道是什么决定将返回所有可能的匹配项中的哪一个。另一方面,您可以使用提供的列表功能编写一个包装程序,该包装程序可以更好地进行搜索,并且可能基于其他一些属性(例如,对窗口的最后访问的时间戳),通过查询提供的胜利可以获得该包装器例如,将ID设置为xprop。
下面的这些代码行返回最近的实例的mate-terminal类窗口:
1 2 3 4 5 6 7 8 9 | 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(" ") }' > $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 |
无论如何,对于您描述的东西正在构建的东西–如果我是您,我将找出所需命令生成的窗口类别,然后基于该窗口而不是PID进行搜索。或者,您可以假定命令CMD可能会生成带有包含CMD的类名的窗口。
找到线后,应使用窗口ID
通过wmctrl激活窗口。
希望这可以帮助。
旁注:我发现xdotool也可以基于类名和窗口标题进行搜索,但是它非常慢。在我的计算机上,此bash脚本(调用了许多外部实用程序)的速度是xdotool:P的已编译替代方法的10倍。
这是几种X11窗口管理解决方案(包括一个针对此问题的解决方案)。
Xwininfo和xprop是获取所有窗口ID的好工具,但不是获取与PID关联的主窗口ID的最简单工具(如果可能的话)。要获取主窗口的ID,请通过以下方式使用wmctrl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/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 |
例:
1 2 | user ~ $ getwindidbypid 37248 0x05a00012 |
如果wmctrl找到多个主窗口,则此解决方案将打印多个Window ID。要仅返回第一个,只需将
您可以使用:
1 | xdotool getwindowfocus getwindowname |
(原样:您不需要用任何东西替换那些听起来不错的名称。)