eshell TRAMP 找到具有相对路径的远程文件(或至少小于完整的 TRAMP 路径)?

eshell TRAMP find remote file with relative path (or at least less than the full Tramp path)?

我喜欢 eshell 的 TRAMP 集成。有了它,我可以 cd /ssh:foo:/etc ssh 进入远程机器并访问它的 /etc/ 目录。我也可以 find-file motd 在我本地的 emacs 中打开这个文件。但是,如果我需要使用 sudo 来更改文件怎么办?我知道我可以给 完整路径,像这样:

find-file /sudo:foo:/etc/motd

但是有没有一种方法可以通过 TRAMPs sudo 支持打开文件,而无需键入完整路径?

我想出了以下适合我的 eshell 别名:

alias sff 'find-file "${pwd}/"(:s/ssh/sudo/)'

它的作用应该很明显。它前置工作目录 路径,但将字符串 ssh 替换为 sudo。因此它只适用于 通过 ssh 访问的远程文件。我很少在本地使用 sudo 编辑文件,所以 这对我来说不是问题。然而,我们也可以让它适用于本地文件,但代价是复杂性:

alias sff 'find-file "${pwd}/"(:s,^,/sudo::,:s,::/ssh:,:,)'

也就是说,在前面添加 /sudo::(这是对本地文件执行 sudo 的方法)和 随后用 : 替换任何出现的 ::/ssh:。 (我会直接删除 :/ssh:,但是 eshell 的 :s/// 构造不接受空的 更换。)

我在 EmacsWiki 找到了一个非常有效的备选答案。 使用它你仍然会像往常一样用 find-file 打开文件,但是 调用 M-x sudo-edit-current-file(如下所示)以 root 身份重新打开文件 使用流浪汉。我认为这是一个非常优雅的解决方案,因为我经常 一开始只是想看个文件,后来发现需要编辑一下

这是函数,以防它从上面的页面中消失:

(set-default 'tramp-default-proxies-alist (quote ((".*" "\`root\'" "/ssh:%h:"))))
(require 'tramp)
(defun sudo-edit-current-file ()
  (interactive)
  (let ((position (point)))
    (find-alternate-file
     (if (file-remote-p (buffer-file-name))
         (let ((vec (tramp-dissect-file-name (buffer-file-name))))
           (tramp-make-tramp-file-name
            "sudo"
            (tramp-file-name-user vec)
            (tramp-file-name-host vec)
            (tramp-file-name-localname vec)))
       (concat "/sudo:root@localhost:" (buffer-file-name))))
    (goto-char position)))