Tramp-Mode 不会与 sudo shell 断开连接?

Tramp-Mode does not disconnect from sudo shell?

我使用 emacs 的 tramp-mode 编辑 root 拥有的文件,语法为 /sudo::<filepath>

这非常有效,但我似乎无法在不通过 h​​top 或其他进程管理器手动终止子进程的情况下让 tramp 结束 sudo 会话。 tramp-cleanup-*-connection 命令不会结束会话。

如何让 emacs 结束 sudo 会话?理想情况下,我希望它在所有 sudo 打开的缓冲区都被杀死后结束会话。

我不知道你为什么说"The tramp-cleanup-*-connection commands do not end the session";我的快速测试表明 tramp-cleanup-this-connection 强制 Tramp 在我下次尝试做某事时重新连接。 (它单独缓存密码,因此您不一定会收到密码提示;但您应该在 *Messages* 缓冲区中看到 "Opening connection"。)

这里简要介绍了一个可以添加到 kill-buffer-hook 的功能。它不是很优雅,但它似乎工作。

(defun tramp-cleanup-sudo-maybe ()
  "If the current buffer is a Tramp \"/sudo:\" buffer, cleanup its connection
if there are no other sudo buffers remaining after killing this one."
  (save-match-data
    (let ((name (buffer-file-name))
          prefix buffers)
      (when (and name (string-match "\`\(/sudo:[^:]*:\)" name))
        (setq prefix (match-string 1 name))
        (mapc (lambda (buf)
                (when (string-prefix-p prefix (or (buffer-file-name buf) ""))
                  (setq buffers (cons buf buffers)) ))
              (buffer-list) )
        (when (< (length buffers) 2)
          (tramp-cleanup-this-connection) ) ) )))

如果您有很多缓冲区,这可能会变慢。如果您觉得需要优化它,我想您可以将每个远程连接计数之类的东西添加到您自己的 alist(或者可能添加到某些现有的 Tramp 连接结构)。或者实际上只是将缓冲区列表的长度(减一,对于我们将要杀死的缓冲区)存储在一个全局变量中,然后在下一次调用时,简单地递减它——只有当它达到零时,再次扫描所有缓冲区并重新初始化变量;如果它确实是最后一个带有这个前缀的 sudo 缓冲区,则进行清理。