
我有幾個 Emacs (v21.2.1) 實例在遠端工作站上運行,我想通過ssh
.當 ssh 進入工作站時,我可以取得每個實例的 PID(pgrep emacs
例如使用 ),但我不知道如何確定哪些進程開啟了特定檔案。
lsof
不會回傳任何明顯有用的信息,大概是因為 Emacs 在緩衝區中編輯文件時不會保持文件開啟狀態。也許可以將現有的 Emacs 視窗匯出到我目前的位置,但我不知道該怎麼做。
我是否愚蠢地認為這是可能的?
答案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
答案2
如果你正在跑步格努塞爾(XEmacs 伺服器的 GNU Emacs 連接埠),或如果您在 GNU Emacs ≥23 上執行包含的 emacsserver,則可以在正在執行的 Emacs 實例中執行任意 Lisp 命令。
gnuclient -r /tmp/gsrvdir1234/gsrv -batch -eval '(buffer-list)'
emacsclient -r /tmp/emacs1234/server -e '(buffer-list)' # Emacs ≥23 only
否則我只能想到兩種非常hackish的方法。
- 在 Emacs 實例的記憶體中搜尋檔案名稱。在Linux上,進程的映射記憶體位於
/proc/$pid/mem
,但您只能讀取實際映射的頁面,透過 可以讀取/proc/$pid/maps
。我不知道現有的程序。 - 開啟包含漏洞的文件局部變數聲明,即允許執行任意 Lisp 程式碼的程式碼。除非另有說明,否則 Emacs 21 仍然將局部變數視為安全的,因此肯定有一些變數應該被聲明為有風險,但實際上卻沒有。但我不知道任何例子。