1

У меня есть несколько экземпляров Emacs (v21.2.1), запущенных на удаленной рабочей станции, один из которых я хотел бы убить с помощью ssh . Я могу получить PID каждого экземпляра (например, используя pgrep emacs ), пока ssh'd на рабочую станцию, но я не знаю, как определить, какой из этих процессов имеет определенный открытый файл.

lsof не возвращает никакой информации, которая явно полезна, предположительно потому, что Emacs не сохраняет файлы открытыми, пока они редактируются в буфере. Может быть, можно экспортировать существующие окна Emacs в мое текущее местоположение, но я не знаю, как мне это сделать.

Разве я глуп, думая, что это вообще возможно?

2 ответа2

1

Используйте strace чтобы увидеть, какие файлы у него открыты (он держит вещи открытыми или, по крайней мере, часто проверяет файлы). Это должно дать вам список всего, на что смотрит процесс, очевидно, вам придется немного разобрать его и отфильтровать дубликаты (и заменить правильный pid):

strace -p1337 -e trace=file

Он генерирует вывод так:

unlink("/tmp/emacsBYJwbf")              = 0
stat("/home/tjackson/.jabber-avatars", {st_mode=S_IFDIR|0755, st_size=16384, ...}) = 0
stat("/home/tjackson/.jabber-avatars/e7e63a04ac20783855bc31ab8fcfb7bc23a39036.jpg", {st_mode=S_IFREG|0644, st_size=2556, ...}) = 0
stat("/lab_scratch/mymachine/work/path/to/some/file.cxx", {st_mode=S_IFREG|0644, st_size=45772, ...}) = 0
open("/lab_scratch/mymachine/work/path/to/some/file.cxx", O_RDONLY) = 10
stat("/lab_scratch/mymachine/work/path/to/some/file.cxx", {st_mode=S_IFREG|0644, st_size=45772, ...}) = 0
stat("/lab_scratch/mymachine/work/some/other/path/different/header_file.h", {st_mode=S_IFREG|0644, st_size=92260, ...}) = 0
open("/lab_scratch/mymachine/work/some/other/path/different/header_file.h", O_RDONLY) = 10
stat("/lab_scratch/mymachine/work/some/other/path/different/header_file.h", {st_mode=S_IFREG|0644, st_size=92260, ...}) = 0
stat("/home/tjackson/News/drafts/drafts/272", 0x7fbfffd400) = -1 ENOENT (No such file or directory)
stat("/scratch2/complex/tmp/output.log", {st_mode=S_IFREG|0644, st_size=378306, ...}) = 0
open("/scratch2/complex/tmp/output.log", O_RDONLY) = 10
stat("/scratch2/complex/tmp/output.log", {st_mode=S_IFREG|0644, st_size=378306, ...}) = 0
stat("/home/tjackson/.diary", {st_mode=S_IFREG|0644, st_size=72457, ...}) = 0
open("/home/tjackson/.diary", O_RDONLY) = 10
stat("/home/tjackson/.diary", {st_mode=S_IFREG|0644, st_size=72457, ...}) = 0
stat("/home/tjackson/News/drafts/drafts/271", 0x7fbfffd400) = -1 ENOENT (No such file or directory)
stat("/home/tjackson/News/drafts/drafts/273", 0x7fbfffd400) = -1 ENOENT (No such file or directory)
stat("/home/tjackson/personal/.newsrc-dribble", 0x7fbfffd400) = -1 ENOENT (No such file or directory)
stat("/lab_scratch/mymachine/work/sandbox/TAGS", {st_mode=S_IFREG|0644, st_size=2578671, ...}) = 0
open("/lab_scratch/mymachine/work/sandbox/TAGS", O_RDONLY) = 10
stat("/lab_scratch/mymachine/work/sandbox/TAGS", {st_mode=S_IFREG|0644, st_size=2578671, ...}) = 0
0

Если вы используете Gnuserv (порт GNU Emacs сервера XEmacs) или если вы запускали включенный emacsserver в GNU Emacs ≥23, вы можете запускать произвольные команды Lisp в запущенном экземпляре Emacs.

gnuclient -r /tmp/gsrvdir1234/gsrv -batch -eval '(buffer-list)'
emacsclient -r /tmp/emacs1234/server -e '(buffer-list)'  # Emacs ≥23 only

В противном случае я могу думать только о двух очень хакерских способах

  • Найдите в памяти экземпляра Emacs имя файла. В Linux отображаемая память процесса находится в /proc/$pid/mem, но вы можете читать только те страницы, которые на самом деле отображаются, как доступные для чтения через /proc/$pid/maps . Я не знаю о существующей программе для этого.
  • Откройте файл, содержащий уязвимое объявление локальной переменной, т. Е. Файл, который позволяет выполнять произвольный код на Лиспе. Emacs 21 по-прежнему рассматривал локальные переменные как безопасные, если не указано иное, поэтому наверняка были переменные, которые должны были быть объявлены как рискованные, но не были. Я не знаю ни одного примера.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .