web-dev-qa-db-ja.com

特定のプロセスIDに関連付けられたウィンドウIDを決定するLinuxコマンドはありますか?

プロセスIDがXXである場合、_NET_WM_PID = XXであるウィンドウIDのリストが必要です。可能であれば、最もアクティブなウィンドウIDがさらに良いでしょう。

私はLinuxが初めてですが、私がやろうとしているのは、コマンドラインを使用するスクリプトを作成し、同じコマンドラインで呼び出されたプロセスに属するウィンドウが既に開いているかどうかを確認することです。その場合は、そのウィンドウにフォーカスを設定するか、コマンドラインを実行して新しいプロセスを開始します。私の意図はubuntuデスクトップでこれを使用して、このスクリプトをイージーストロークのマウスジェスチャーコマンドにフックすることです既存のgmail chromeアプリウィンドウに移動します。おそらく、これらすべてを実行するためのはるかに簡単な方法がありますが、私はまだその方法を見つけていません。

助けを借りて、pgrepを使用してコマンドラインのPIDを見つける方法と、wmctrlを使用してウィンドウハンドルにフォーカスを設定する方法を見つけましたが、PIDからウィンドウIDへの移動に固執しています。

35
David Korn

xwininfoとxpropは必要なものを取得することを許可しますが、少し注意が必要です。

xwininfoは、既知のすべてのウィンドウを取得することを許可し、xpropは、_NET_WM_PIDパラメーターの単一のウィンドウIDについてXを照会します。

これまでのところ、それを行うためのハッキング方法は次のとおりです。

#!/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

ご覧のとおり、画面上に1つしか表示されていない場合でも、1つのプロセスには特定の数の既知のウィンドウが存在する場合があります。

たぶん、あなたはあなたが望むものを作るためにこれらのツールソースを手に入れるべきです。

37
Patrick

wmctrlでPIDを検索することもできますが、実際にはそれがより良い方法だと思います。 xwininfoは、ウィンドウのように見えるすべての種類のエンティティを返しますが、実際にはデスクトップでそれらを見つけることはできません。

man wmctrlを実行すると、wmctrl -lがデスクトップ上に実際に表示されるすべてのウィンドウを(最も重要なことですが)window idsおよびtitles-pが追加されますPIDs-xが追加されますwindow classes

マニュアルに記載されているように(RTFM、正しい?:D)、wmctrlはこれらの一部を検索し、検索に一致するウィンドウをアクティブにすることもできます。ただし、一致する可能性のあるもののどれが返されるかはわかりません。一方、提供されたリスティング関数を使用して、提供されたクエリを実行することで取得できる他のプロパティ(ウィンドウへの最後のアクセスのタイムスタンプなど)に基づいて検索を行うラッパーを作成できます。 win 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 -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を含むクラス名を持つウィンドウを生成する可能性があると想定できます。

行を見つけたら、window idを使用する必要があります
wmctrlを介してウィンドウをアクティブにします。

お役に立てれば。

補足:xdotoolはクラス名とウィンドウタイトルにも基づいて検索できることを発見しましたが、extremely slowです。私のコンピューターでは、このbashスクリプト(かなりの数の外部ユーティリティを呼び出します)は、xdotool:Pであるコンパイルされた代替の10倍の速度です。

25
PSkocik

ここ は、いくつかのX11ウィンドウ管理ソリューション(この問題に対するものを含む)です。

Xwininfoとxpropは、すべてのウィンドウのIDを取得するための優れたツールですが、PIDに関連付けられているプラ​​イマリウィンドウの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を出力します。最初のものだけを返すには、単に[@]から[0] in echo "${WIND_IDS[@]}"

3

次を使用できます。

xdotool getwindowfocus getwindowname

(現状のまま:それらのニースのような名前を何かで置き換える必要はありません。)

2
Richard