Я испытал затруднения, заставив экран поддерживать utf-8 и 256 цветов, но tmux работал из поля.
Если Ваш X-сервер не поддерживает XResQueryClientIds
от X-ресурса v1.2 расширение я не знаю простого способа надежно запросить идентификатор процесса. Существуют другие пути как бы то ни было.
Если Вы просто имеете окно перед Вами и еще не знаете его идентификатор — легко узнать это. Просто откройте терминал рядом с рассматриваемым окном, работайте xwininfo
там и нажимают на то окно. xwininfo
покажет Вам идентификатор окна.
Поэтому давайте предположим, что Вы знаете идентификатор окна, например, 0x1600045, и хотите найти, что процесс владеет им.
Самый легкий способ проверить, кому принадлежит то окно, состоит в том, чтобы выполнить XKillClient для него т.е.:
xkill -id 0x1600045
и посмотрите, какой процесс просто умер. Но только если Вы не возражаете уничтожать его, конечно!
Другой легкий, но ненадежный путь состоит в том, чтобы проверить _NET_WM_PID
и WM_CLIENT_MACHINE
свойства:
xprop -id 0x1600045
Это что инструменты как xlsclients
и xrestop
сделать.
К сожалению, эта информация может быть неправильной не только потому, что процесс был злым и изменил их, но также и потому что это был багги. Например, после некоторого катастрофического отказа/перезапуска Firefox я видел осиротевшие окна (от флеш-плагина, я предполагаю) с _NET_WM_PID
указывая на процесс, который умер давным-давно.
Альтернативный путь состоит в том, чтобы работать
xwininfo -root -tree
и проверьте свойства родителей рассматриваемого окна. Это может также дать Вам некоторые подсказки об источниках окна.
Но! В то время как Вы не можете найти, какой процесс создали то окно, существует все еще способ найти, откуда тот процесс соединился с X-сервером. И тот путь для настоящих хакеров.:)
Идентификатор окна 0x1600045, который Вы знаете с более низкими обнуленными битами (т.е. 0x1600000) является "клиентурой". И все идентификаторы ресурса, выделенные для того клиента, базируются на нем (0x1600001, 0x1600002, 0x1600003, и т.д.). X-сервер хранит информацию о своих клиентах в клиентах [] массив, и для каждого клиента ее "основа" хранится в клиентах [я]-> clientAsMask переменная. Для нахождения X-сокета, соответствуя тому клиенту, необходимо подключить к X-серверу с gdb
, клиенты технической победы [] массив, найдите клиент с этим clientAsMask
и распечатайте его дескриптор сокета, сохраненный в ((OsCommPtr) (клиенты [я]-> osPrivate))-> fd.
Может быть много соединенных X-клиентов, поэтому для не проверки их всех вручную, давайте использовать функцию gdb:
define findclient
set $ii = 0
while ($ii < currentMaxClients)
if (clients[$ii] != 0 && clients[$ii]->clientAsMask == $arg0 && clients[$ii]->osPrivate != 0)
print ((OsCommPtr)(clients[$ii]->osPrivate))->fd
end
set $ii = $ii + 1
end
end
При нахождении сокета можно проверить, кто подключен к нему, и наконец найдите процесс.
ПРЕДУПРЕЖДЕНИЕ: НЕ подключайте gdb к X-серверу ИЗ X-сервера. gdb приостанавливает процесс, который он присоединяет к, поэтому если Вы присоедините к нему из X-сессии, то Вы заморозите свой X-сервер и не сможете взаимодействовать с gdb. Необходимо или переключиться на текстовый терминал (Ctrl+Alt+F2
) или соединитесь со своей машиной по ssh.
Найдите PID своего X-сервера:
$ ps ax | grep X
1237 tty1 Ssl+ 11:36 /usr/bin/X :0 vt1 -nr -nolisten tcp -auth /var/run/kdm/A:0-h6syCa
Идентификатор окна является 0x1600045, таким образом, клиентура является 0x1600000. Подключите к X-серверу и найдите клиентский дескриптор сокета для той клиентуры. Вам будет нужна отладочная информация, установленная для X-сервера (-debuginfo пакет для дистрибутивов об/мин или-dbg пакет для deb's).
$ sudo gdb
(gdb) define findclient
Type commands for definition of "findclient".
End with a line saying just "end".
> set $ii = 0
> while ($ii < currentMaxClients)
> if (clients[$ii] != 0 && clients[$ii]->clientAsMask == $arg0 && clients[$ii]->osPrivate != 0)
> print ((OsCommPtr)(clients[$ii]->osPrivate))->fd
> end
> set $ii = $ii + 1
> end
> end
(gdb) attach 1237
(gdb) findclient 0x1600000
$1 = 31
(gdb) detach
(gdb) quit
Теперь Вы знаете, что клиент подключен к сокету сервера 31. Использовать lsof
для нахождения, каков тот сокет:
$ sudo lsof -n | grep 1237 | grep 31
X 1237 root 31u unix 0xffff810008339340 8512422 socket
(здесь "X" имя процесса, "1237" его pid, "корень" является пользователем, от которого это работает, "31u" дескриптор сокета),
Там можно видеть, что клиент соединен по TCP, затем можно перейти к машине, от которой он соединен, и проверить netstat -nap
там найти процесс. Но по всей вероятности Вы будете видеть сокет Unix там, как показано выше, что означает, что это - локальный клиент.
Для нахождения пары для того сокета Unix, можно использовать технику MvG (Вам также будет нужна отладочная информация для Вашего установленного ядра):
$ sudo gdb -c /proc/kcore
(gdb) print ((struct unix_sock*)0xffff810008339340)->peer
$1 = (struct sock *) 0xffff810008339600
(gdb) quit
Теперь, когда Вы знаете клиентский сокет, использовать lsof
найти PID, содержащий его:
$ sudo lsof -n | grep 0xffff810008339600
firefox 7725 username 146u unix 0xffff810008339600 8512421 socket
Именно. Процесс, сохраняющий то окно, является "Firefox" с идентификатором процесса 7725
Редактирование 2017 года: существует больше опций теперь, как замечено в том, у Кого есть другой конец этого Unix socketpair?. С Linux 3.3 или выше и с lsof
4.89 или выше, можно заменить точки 3 - 5 выше с:
lsof +E -a -p 1237 -d 31
узнать, кто в другом конце сокета на fd 31 процесса X-сервера с идентификатором 1237.
Если у Вас есть установленный xdotool, то
xdotool selectwindow getwindowpid
сопровождаемый путем нажатия на рассматриваемое окно возвратит PID.
(Существуют другие способы выбрать рассматриваемое окно, например, если у Вас есть его окно ID, можно просто сделать xdotool getwindowpid <number>
. Можно также выбрать по имени или класс, и т.д.),
Я действительно думаю, что это требует некоторых играющих по правилам от имени WM. Я не экспериментировал очень, или должен был.
xdo_getwinprop(xdo, window, atom_NET_WM_PID, &nitems, &type, &size)
⇒ это - просто обертка оболочки для чтения _NET_WM_PID
(полезный, но не, что я попросил).
– Gilles 'SO- stop being evil'
07.01.2011, 01:44
_NET_WM_PID
не установлен менеджером окон (как просто другой клиент X11, как он знал бы?).
Вместо этого совместимые клиенты X11 (приложения), как ожидают, установят _NET_WM_PID
и WM_CLIENT_MACHINE
на их собственных окнах. Принимая приложение хорошего поведения, это будет верно, работает ли менеджер окон или нет.
Если WM_CLIENT_MACHINE
Ваше собственное имя хоста, затем PID должен быть значимым.
Иначе "я хотел бы IP и порт, связанный с удаленным концом" — я не уверен, что это означает. Например, если у Вас будет ssh сессия, открытая с X включенными передачами, то окна, открытые переданными приложениями, будут отмечены с удаленным PID и именем хоста, но у Вас не обязательно есть любой способ соединиться назад с тем удаленным хостом.
_NET_WM_PID
установлен приложением: право, которое действительно имеет больше смысла! Но это не протокол X11, это - относительно недавняя спецификация FreeDesktop.
– Gilles 'SO- stop being evil'
08.01.2011, 14:26
_NET_WM_PID
кажется, установлен на удаленный PID и WM_CLIENT_MACHINE
к удаленному соединению (протестированный с xterm).
– Gilles 'SO- stop being evil'
08.01.2011, 14:26
Я смог использовать xdotool
под бетой Ubuntu 11.04, но selectwindow
если бы допустимый команда не был, то я должен был взломать сценарий с:
$ while true; do sleep 1; xdotool getactivewindow; done
затем наблюдайте, что окно ID проходит, в то время как я выбрал окно, я хотел, затем декодировал ответственный PID с:
$ xdotool getwindowpid <the-window-id>
xdotool не работал на меня. Это сделало:
Выполненный
xprop _NET_WM_PID
и нажмите на окно.
Это основано на ответе по http://www.linuxquestions.org/questions/linux-software-2/advanced-question-finding-pid-of-an-x-window-328983/
kill $(xprop _NET_WM_PID|cut -d " " -f 3)
– Gabriel Devillers
09.10.2016, 14:38