使用 Emacs 通过 SSH 和 Sudo 打开文件

我想在 Emacs 中打开一个文件,它位于远程服务器上,在服务器上具有 sudo 权限。我可以像下面这样用 sudo 打开本地文件:

C-x C-f /sudo::/home/user/file

但是我想在服务器上使用 sudo:

C-x C-f /sudo::user@server/home/user/file

但是这会在我的本地机器上赋予我 sudo 权限,它会在本地机器上询问我的 sudo 密码。有没有在服务器上使用 sudo 的方法?

顺便说一下: 服务器上没有安装 Emacs

43599 次浏览

首先必须 ssh 到服务器,然后必须在本地运行 emacs。

或者可以使用没有 _ root _ squash 的 NFS,或者可以尝试使用 emacs 服务器/客户端,尽管我不知道会发生什么(我自己不使用 emacs)

更新 : 虽然这个答案解决了最初的问题,但它是为 emacs 20或21编写的。对于 emacs 24,我建议您使用 Phil 的回答,因为它提供了更多的解释,并且是最新的。


我认为 多跳文件名多跳文件名在流浪汉是你要找的。

第一个跳将是 ssh,第二个跳将是 sudo。


更新: 最新版本的 emacs 支持使用代理的多跳:

(add-to-list 'tramp-default-proxies-alist ("my-sudo-alias" nil "/ssh:user@ssh-host"))

然后打开:

/sudo:my-sudo-alias:file-on-ssh-host

我在选择答案时遇到了一些问题。但是,当我将这一行添加到.emacs 中时,它起作用了:

(add-to-list 'tramp-default-proxies-alist '(".*" "\\`root\\'" "/ssh:%h:"))

And then executed the following:

/sudo:ssh-host:file-on-ssh-host

这有点令人困惑,因为有一次我被提示输入“ root”密码,但输入用户的密码授予了我访问权限。它也普遍适用于网络上的所有主机。另外,我还可以这样做不是根:

/ssh:ssh-host:file-on-ssh-host

来自 tramp multi-hops configuration webpage

 (add-to-list 'tramp-default-proxies-alist
'(nil "\\`root\\'" "/ssh:%h:"))
(add-to-list 'tramp-default-proxies-alist
'((regexp-quote (system-name)) nil nil))

那么任何

C-x C-f /sudo:remote-host:/file

使用远程计算机上运行 emacs 的用户的相同用户名登录后,将使用 Sudo打开文件。

从 Emacs 24.3开始,旧的 multi:语法的模拟已经在现代 tramp-default-proxies-alist方法之上进行了分层,这意味着您可以再次执行多跳,而不需要任何先前的配置。有关详情,请参阅:

C-hig (tramp)Ad-hoc multi-hops RET

使用新的语法,每个“跃点”由 |分隔。手册中的例子是:

C-xC-f /ssh:bird@bastion|ssh:you@remotehost:/path RET

它首先连接 bird@bastion,然后从那里连接到 you@remotehost:/path

/su: 或/sudo: 在远程主机上

You can also use this syntax to sudo/su to root (or of course any other user) on a remote host:

C-xC-f /ssh:you@remotehost|sudo:remotehost:/path/to/file RET

Important: be sure to specify the hostname explicitly: sudo:remotehost: rather than sudo:: (see below).

因为它仍然使用底层的代理机制,所以 tramp-default-proxies-alist现在应该包含值 ("remotehost" "root" "/ssh:you@remotehost:")

这意味着无论何时请求一个文件作为 root@remotehost,都将使用代理 /ssh:you@remotehost:

root是这些方法的默认用户,但是您当然也可以通过以下方式更改为非 root 用户:

C-xC-f /ssh:you@remotehost|sudo:them@remotehost:/path/to/file RET

始终显式指定远程主机名

You are probably used to using sudo:: or su:: and omitting the hostname. If you are 留下来 on the localhost then this is still fine, but if you are hopping to a remote server then you 必须的 specify the hostname for every hop -- even if it is the same as for the previous hop. Always use sudo:hostname: or su:hostname: with remote hosts.

这里的陷阱是,sudo:: 是的实际上似乎可以工作——当您这样做时,动态代理条目的 HOST 将是您 起源于的主机名,而不是您连接到的主机名。这不仅看起来令人困惑(因为文件路径中将显示错误的主机) ,而且还意味着任何后续尝试在本地主机上使用 sudo::的操作都将被代理到远程服务器!(如果您在第二台服务器上执行相同的操作,代理可能也会受到重创,从而导致进一步的问题)。

总之,不要使用 ::时,你多跳!

Emacs 27 +

Starting from Emacs 27.1 (or Tramp 2.4.2, if using the GNU ELPA package) the :: case works intuitively, such that /ssh:you@remotehost|sudo:: will re-use remotehost rather than your own local host, and so you won't end up with a bad proxy entry.

此外,检测到类似 /ssh:you@remotehost|sudo:localhost:的错误并将其标记为用户错误。

如果你倾向于使用 Emacs 的混合版本,包括早于27版本的版本(或者你建议其他人使用旧版本) ,那么在多跳时继续将 ::视为不安全的版本是最安全的,以避免潜在的事故。(也就是说,如果 Tramp 版本未知,显式指定正确的远程主机仍然是最安全的方法。)