给定一个XX的进程ID,我想有一个窗口ID的列表,其中_NET_WM_PID = XX。 如果可能的话,更好的是最老的活动窗口ID。
我是非常新的Linux,但我想要做的是创build一个脚本,将采取命令行,并查看是否有一个已经打开的窗口属于一个进程调用该命令行。 如果是这样,只需将焦点设置到该窗口,否则执行命令行来获取新的进程。 我的意图是在我的Ubuntu桌面上使用这个,在那里我将钩子脚本到我的easystroke鼠标手势命令,所以,例如,每当我为gmail手势,我没有得到一个全新的gmail会话,我只是拿到我现有的Gmail Chrome浏览器应用程序窗口。 也许有更简单的方法去解决这一切,但是我还没有find办法。
有了帮助,我已经find了如何使用pgrep查找命令行的PID,以及如何使用wmctrl将焦点设置到窗口句柄,但是我一直在从PID获取窗口ID。
xwininfo和xprop允许检索你想要的,但是有点棘手。
xwininfo允许检索所有已知的窗口,并且xprop查询X关于您的_NET_WM_PID参数的单个窗口ID。
到目前为止,做一个黑客的方法是:
#!/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
结果:
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将返回各种似乎是窗口的实体,但你不会真的在你的桌面上找到它们。
如果你做的人wmctrl ,你会发现, wmctrl -l列出了所有窗口,实际上在您的桌面上(最重要的是)他们的窗口ID和标题可见。 -p添加PID , -x将添加窗口类 。
正如手册所说(RTFM,对吧?:D),wmctrl也可以搜索其中的一些,并激活一个匹配搜索的窗口。 但是,我不知道是什么决定了哪一个可能的匹配将被返回。 另一方面,您可以使用提供的列表函数来编写一个可以更好地进行搜索的包装器,并可能基于其他一些属性(例如上次访问窗口的时间戳),通过查询提供的获胜id到xprop,例如。
下面的这些代码行将返回最近的一个对象类窗口:
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 -vs="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倍。
您可以使用:
xdotool getwindowfocus getwindowname
(因为:你不需要用任何东西来替换那些听起来不错的名字。)
我想先提供这个链接到shell解决方案来解决这个和类似的X11窗口管理问题。
使用xwininfo和xprop是一个很好的解决方案,可以返回所有与PID关联的Window ID。 要获取主窗口的ID,可以按照以下方式使用wmctrl:
#!/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
例:
user ~ $ getwindidbypid 37248 0x05a00012
如果wmctrl找到多个主窗口,此解决方案将打印多个窗口ID。 要仅返回第一个,只需在echo "${WIND_IDS[@]}"
更改为[0]
。