Open file via SSH and Sudo with Emacs
I want to open a file inside Emacs which is located on a remote server, with sudo powers on the server. I can open local files with sudo via Tramp like this:
C-x C-f /sudo::/home/user/file
But I want to use sudo on the server:
C-x C-f /sudo::user@server/home/user/file
But this gives me sudo powers on my 开发者_如何学编程local machine, it asks for my sudo password on the local machine. Is there a way to use sudo on the server?
BTW: Emacs is not installed on the server
As of Emacs 24.3, an analog of the old multi:
syntax has been layered on top of the modern tramp-default-proxies-alist
approach, meaning that you can once again perform multi-hops without any prior configuration. For details, see:
C-hig (tramp)Ad-hoc multi-hops
RET
With the new syntax, each 'hop' is separated by |
. The example in the manual is:
C-xC-f /ssh:bird@bastion|ssh:you@remotehost:/path
RET
Which connects firstly as bird@bastion
, and from there to you@remotehost:/path
/su: or /sudo: on remote hosts
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).
As this still uses the proxy mechanism underneath, tramp-default-proxies-alist
should now include the value ("remotehost" "root" "/ssh:you@remotehost:")
Meaning that the proxy /ssh:you@remotehost:
is going to be used whenever you request a file as root@remotehost
.
root
is the default user for these methods, but you can of course also change to a non-root user with:
C-xC-f /ssh:you@remotehost|sudo:them@remotehost:/path/to/file
RET
Always specify the remote hostname explicitly
You are probably used to using sudo::
or su::
and omitting the hostname. If you are staying on the localhost then this is still fine, but if you are hopping to a remote server then you must 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.
The trap here is that sudo::
does actually appear to work -- however when you do that the HOST for the dynamic proxy entry will be the hostname you originated from rather than the host you connected to. This will not only look confusing (as the wrong host will be displayed in the file paths), but it will also mean that any subsequent attempt to use sudo::
on your localhost will instead be proxied to the remote server! (and the proxy would also presumably be clobbered if you did the same thing on a second server, causing further issues).
In short, don't use ::
when you multi-hop!
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.
In addition, the likes of /ssh:you@remotehost|sudo:localhost:
are detected and flagged as user errors.
If you are liable to use a mixture of Emacs versions including versions earlier than 27 (or you are advising someone else who may be using an older version), then it would be safest to continue to treat ::
as unsafe when multi-hopping, to avoid potential mishap. (I.e. specifying the correct remote host explicitly will remain the safest approach if the Tramp version is unknown.)
Update: Although this answer solved the original problem, it was written for emacs 20 or 21. For emacs 24, I recommend you use phils's answer because it offers more explanation and is up to date.
I think multi-hop filenames in tramp is what you're looking for.
The first hop would be ssh and the second would be sudo.
Update: Recent versions of emacs support multiple hops using proxies:
(add-to-list 'tramp-default-proxies-alist ("my-sudo-alias" nil "/ssh:user@ssh-host"))
Then invoke by opening:
/sudo:my-sudo-alias:file-on-ssh-host
I had some troubles with the selected answer. However, it worked when I added this line to .emacs:
(add-to-list 'tramp-default-proxies-alist '(".*" "\\`root\\'" "/ssh:%h:"))
And then executed the following:
/sudo:ssh-host:file-on-ssh-host
It was slightly confusing because at one point I was prompted for the "root" password, but entering my user's password granted me access. It also universally works on all hosts on the network. Also, I can still do this to not be root:
/ssh:ssh-host:file-on-ssh-host
From the 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))
Then any
C-x C-f /sudo:remote-host:/file
will open file using sudo after logged with the same username of the user running emacs but on the remote machine.
You have to ssh into the server first, then you have to run emacs locally.
Or you can use NFS with no_root_squash, or you can try with emacs server/client, although I have no idea of what may happen (do not use emacs myself)
精彩评论