Posso descobrir quais arquivos estão abertos em uma instância do Emacs em execução na estação de trabalho remota?

Posso descobrir quais arquivos estão abertos em uma instância do Emacs em execução na estação de trabalho remota?

Tenho várias instâncias do Emacs (v21.2.1) em execução em uma estação de trabalho remota, uma das quais gostaria de eliminar via ssh. Posso obter os PIDs de cada instância (usando pgrep emacs, digamos) durante o ssh na estação de trabalho, mas não sei como determinar qual desses processos tem um arquivo específico aberto.

lsofnão retorna nenhuma informação que seja obviamente útil, provavelmente porque o Emacs não mantém os arquivos abertos enquanto eles estão sendo editados em um buffer. Talvez seja possível exportar as janelas existentes do Emacs para minha localização atual, mas não sei como faria isso.

Sou tolo em pensar que isso é possível?

Responder1

Usarstracepara ver quais arquivos estão abertos (ele mantém as coisas abertas ou pelo menos verifica os arquivos com frequência). Isso deve fornecer uma lista de tudo o que o processo está analisando, obviamente você terá que analisá-lo um pouco e filtrar as duplicatas (e substituir o pid adequado):

strace -p1337 -e trace=file

Ele gera uma saída como esta:

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

Responder2

Se você estiver correndoGnuserv(uma porta GNU Emacs do servidor XEmacs), ou se você estava executando o emacsserver incluído no GNU Emacs ≥23, você pode executar comandos Lisp arbitrários em uma instância em execução do Emacs.

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

Caso contrário, só consigo pensar em duas maneiras altamente hackeadas.

  • Pesquise na memória da instância do Emacs o nome do arquivo. No Linux, a memória mapeada do processo está em/proc/$pid/mem, mas você só pode ler as páginas que estão realmente mapeadas, como legíveis por meio de /proc/$pid/maps. Não conheço nenhum programa existente para isso.
  • Abra um arquivo contendo um vulneráveldeclaração de variável local, ou seja, aquele que permite a execução de código Lisp arbitrário. O Emacs 21 ainda tratava as variáveis ​​locais como seguras, a menos que indicado de outra forma, então certamente havia variáveis ​​que deveriam ter sido declaradas como arriscadas, mas não foram. Eu não conheço nenhum exemplo.

informação relacionada