在Emacs中使用su/sudo打开文件

189

假设我想在已有的Emacs会话中使用susudo打开文件,而不需要降到shell并执行sudoeditsudo emacs。一种方法是:

C-x C-f /sudo::/path/to/file

但这需要一个昂贵的通过SSH来回连接。是否有更直接的方法?

[编辑] @JBB是对的。我希望能够调用su/sudo来保存和打开文件。重新授权保存时可以,但并不理想。我要寻找的是能够通过su/sudo“管道”传递的find-filesave-buffer的变化。


6
我想指出自从 Emacs22 起,tramp 默认已经安装了,因此大多数人可以轻松地使用 C-c C-f /sudo::/path-to/file,无需任何问题。 - labyrinth
1
感谢提到 sudoedit。非常有用。 - tshepang
6
C-c C-f 应该改为 C-x C-f? - James.Xu
1
“C-x C-f /sudo::/path/to/file” 的文档在哪里可以找到? - young_souvlaki
2
Tramp 在 Emacs 标准手册中有文档。使用 C-h i 进入 Info,然后使用 g (tramp)mTRAMP 转到 Tramp 顶部 Info 节点。进入 Tramp 手册中的第 3.3 节,即 gQuickstart Start Guide: su、sudo 和 sg 方法 - Anders
C-x C-f /su::/path/to/file - elixon
10个回答

70

Tramp的好处在于,当您打开第一个文件时,您只需要支付到SSH的往返费用。Sudo然后缓存您的凭据,Emacs保存一个句柄,因此随后通过sudo打开的文件花费的时间要少得多。

我认为保存所需的额外时间并不会造成负担,速度足够快。


4
等一下...缓存多久过期一次? - Chris Conway
23
Tramp 不通过 SSH 进行往返传输,而是使用一个子 Shell。 - Teddy
我的意思是你只为第一个打开的文件付费,而不是其他任何文件。 - EfForEffort

67

19
如果你使用 helmhelm-find-files 支持使用快捷键 C-c r 以 root 权限打开文件。

这个可以工作,但似乎在会话中是持久的,每个文件随后都会以root身份打开和保存。文档M-x helm-find-files C-c ?中没有说明如何返回到以用户身份打开的正常模式。再次执行C-c r也无法停止它。 - Liam
@Liam 当我使用该功能时,我仍然可以作为普通用户打开文件。 - Qudit
非常奇怪 - 有些文件没问题,有些则试图以 root 身份打开。我用 Emacs 命令和 sudo -k 杀掉了 root 密码,然后它提示输入密码。我重启了 Emacs,但问题并没有消失。我在 .emacs.d 中查找并发现一些关于 tramp 的引用,于是将其删除。现在看起来好多了,但不确定是否已经解决了问题。 - Liam

18

这并不是对原问题的回答,但以下是一个辅助函数,可以使使用Tramp/Sudo路由更加容易:

(defun sudo-find-file (file-name)
  "像查找文件一样打开文件,但该函数会以root身份打开文件。"
  (interactive "FSudo查找文件:")
  (let ((tramp-file-name (concat "/sudo::" (expand-file-name file-name))))
    (find-file tramp-file-name)))

我认为Emacs Starter Kitesk-sudo-edit中有类似的功能。 - mrmagooey

5
至少在保存时,一个名为sudo-save的软件包专门解决了这种问题。你可以访问sudo-save package获取更多信息。

5

你的例子根本没有启动ssh,至少在我的TRAMP版本(“2.1.13-pre”)中不是这样。无论是find-file还是save-buffer都可以很好地工作。


您可能已经缓存了您的凭据。当TRAMP首次启动时,它会经历10-15秒的SSH处理。(我也有2.1.13-pre。) - Chris Conway
你确定吗?我的意思是,它应该启动一个子 shell,而不是到本地主机的 SSH 会话。第一次运行所有 TRAMP 自动嗅探大约需要 5 秒钟。 - jfm3
好的,不,我不确定。我应该说有10-15秒的TRAMP(可能是SSH)内容。我不关心SSH本身,而是关心启动时的延迟。这个启动过程会持续多久? - Chris Conway
1
你只需要一个Emacs进程。 这就是使用TRAMP的原因。 身份验证凭据的“缓存”方式与运行sudossh时完全相同(也就是说,根本不缓存或在ssh-agent中)。 - jfm3
1
如果您的机器缺少FQDN,那么较长的Tramp / SSH启动时间可能是原因之一。 - sjas
显示剩余2条评论

3

我建议您使用“advising commands”(指令建议)来增强技术能力。将此函数放置在您的~/.emacs文件中。

(defadvice ido-find-file (after find-file-sudo activate)
  "Find file as root if necessary."
  (unless (and buffer-file-name
               (file-writable-p buffer-file-name))
    (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))

只是明显的指出,这需要您使用ido-find-file来查找文件。 - tripleee

1

仅在本地工作。需要更新以通过tramp正确工作

稍微扩展一下Burton的答案:

(defun sudo-find-file (file-name)
"Like find file, but opens the file as root."
(interactive "FSudo Find File: ")
(let ((tramp-file-name (concat "/sudo::" (expand-file-name file-name))))
(find-file tramp-file-name)))


(add-hook 'dired-mode-hook
    (lambda ()
      ;; open current file as sudo 
      (local-set-key (kbd "C-x <M-S-return>") (lambda()
        (interactive)
        (message "!!! SUDO opening %s" (dired-file-name-at-point))
        (sudo-find-file (dired-file-name-at-point))
      ))
    )
)

0

唉。也许你可以在Emacs中打开一个shell并执行sudo emacs。

问题是,你可能不只是想打开文件。你还想以后能够保存它。因此,你需要你的root权限持久存在,而不仅仅是为了打开文件而存在。

听起来你想让Emacs成为你的窗口管理器。它已经足够臃肿了,不需要再加上这个功能。 :)


12
哈哈,你说了“膨胀”(bloat)。Emacs曾经看起来非常庞大。但是与Java、Ruby和可能还有其他东西的运行时占用相比,它现在看起来相当精简。无论如何,我认为Chris的问题涉及Emacs的完全合法的用途。 - jfm3
2
你比我快了。我一直使用这个模型。在登录时,我会启动一个Emacs会话用于一般事务,一个用于SU访问(作为root),以及一个或多个用于软件开发(通常是按项目划分,但不总是)。我已经这样做多年了。非常好用。 - pajato0
你能否澄清如何执行以下操作:“在Emacs中打开一个shell并执行sudo emacs”? - johnbakers
2
@OpenLearner,说真的,你不想这么做。 - tripleee
这是一个糟糕的建议,因为我们有TRAMP,可以像任何其他文件一样使用/sudo::/file打开(或写入)文件,而不会出现任何问题。不,它不会启动任何SSH会话,除非您告诉Emacs该文件应在远程机器上打开。 - Anders
1
你可以通过提供一种新的、更现代的解决方案来升级答案。在这种情况下,您基本上需要说明为什么旧的解决方案并不那么好(即使我们通过安全眼镜看它时,它当时就很糟糕)。当时还有AngeFTP,如果您想要一个当时可用的模式。据我所见,Tramp可以追溯到1999年,但我可能有错。 - Anders

0

我发现sudo edit功能非常有用。打开文件后,按下s-e即可获得sudo访问权限以编辑/保存文件。


我没有超级键。s-e 调用哪个功能? - pglpm
1
调用了sudo-edit函数。 - Daoist Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接