192

Suppose I want to open a file in an existing Emacs session using su or sudo, without dropping down to a shell and doing sudoedit or sudo emacs. One way to do this is

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

but this requires an expensive round-trip through SSH. Is there a more direct way?

[EDIT] @JBB is right. I want to be able to invoke su/sudo to save as well as open. It would be OK (but not ideal) to re-authorize when saving. What I'm looking for is variations of find-file and save-buffer that can be "piped" through su/sudo.

5
  • 7
    I just wanted to note that tramp comes installed by default since emacs22, so most people can just do the C-c C-f /sudo::/path-to/file without problem. Commented May 29, 2012 at 0:37
  • 7
    C-c C-f should be C-x C-f? Commented Aug 26, 2013 at 6:49
  • 1
    Where is C-x C-f /sudo::/path/to/file documented? Commented Apr 19, 2021 at 15:53
  • 2
    Tramp is documented in Emacs standard manual. Start info with C-h i then goto Tramp top info noed with g (tramp), or mTRAMP. Go to gQuickstart Start Guide: su, sudo and sg methods which is section 3.3 in Tramp manual. Commented Feb 7, 2022 at 16:54
  • C-x C-f /su::/path/to/file Commented May 24, 2022 at 22:32

12 Answers 12

71

Tramp does not round-trip sudo via SSH, it uses a subshell. See the manual: https://www.gnu.org/software/tramp/#Inline-methods

Therefore, I recommend that you stick with TRAMP.

Sign up to request clarification or add additional context in comments.

3 Comments

I'd like to believe this, but currently when I attempt to open, say, /var/log/messages via sudo::/var/log/messages, I get an error buffer that says: ssh: connect to host $myhost port 22: Connection refused. Is it a configuration thing?
@Apteryx: A colleague of mine had a similar issue, and the reason was that they had initially used /ssh:localhost|sudo:localhost: and as a consequence of that they had acquired an ad-hoc proxy which caused /ssh:localhost: to happen if they tried to /sudo::. See stackoverflow.com/a/16408592 for more details. M-x tramp-cleanup-all-connections is a quick way to flush ad-hoc proxies (and various other state).
I've since also learned that if you use counsel/ivy, you need to be extra careful when entering the TRAMP pseudo file name, making sure the file name at the minibuffer starts with /, which means C-x C-f //sudo::/var/log/messages in my case (note the double slash).
70

The nice thing about Tramp is that you only pay for that round-trip to SSH when you open the first file. Sudo then caches your credentials, and Emacs saves a handle, so that subsequent sudo-opened files take much less time.

I haven't found the extra time it takes to save burdening, either. It's fast enough, IMO.

3 Comments

Wait a second... How often does the cache expire?
Tramp does not round-trip via SSH, it uses a subshell.
My point was really that you pay the cost for the first opened file, and not for any of the others.
19

If you use helm, helm-find-files supports opening a file as root with C-c r.

3 Comments

This works, but it seems to be persistent in a session, every file subsequently is opened and saved as root. There is nothing in the documentation M-x helm-find-files C-c ? that tells how to return to the normal mode of opening as the user. Doing C-c r again does not stop it.
@Liam I am still able to open file as a normal user when I use that feature.
It's very odd - some files are fine, some it tries to open as root. I killed the root password with emacs commands and sudo -k and then it prompts for the password. I restarted Emacs and that didn't eliminate the problem. I dug around in .emacs.d and found some references to tramp so I deleted those. Now it seems better but not sure if I'm free of it.
18

Not really an answer to the original question, but here's a helper function to make doing the tramp/sudo route a bit easier:

(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))) 

1 Comment

I think the Emacs Starter Kit has a something similar in esk-sudo-edit.
5

Your example doesn't start ssh at all, at least not with my version of TRAMP ("2.1.13-pre"). Both find-file and save-buffer work great.

7 Comments

You may have your credentials cached. When TRAMP first starts up, it goes through 10-15 seconds of SSH stuff. (I've got 2.1.13-pre too.)
Are you sure? I mean, it should be starting a subshell, but not a SSH session to localhost. Takes about 5 seconds to run all the TRAMP auto-sniffage the first time.
Well, no, I'm not sure. I should say there's 10-15 seconds of TRAMP (maybe SSH) stuff. I'm not concerned about SSH per se, but about the lag in starting up. How long does this startup stuff persist?
You should only ever need one Emacs process. That's the point of using TRAMP in the first place. Authentication credentials are "cached" in a manner identical to how they are when you run sudo or ssh (that is to say, not at all, or in an ssh-agent).
Longer tramp / ssh startup may be due to your machine lacking a FQDN iirc.
|
5

At least for saving, a sudo-save package was written exactly for that kind of problem.

Comments

3

I recommend you to use advising commands. Put this function in your ~/.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)))) 

1 Comment

Just to point out the obvious, this requires that you are using ido-find-file to find files.
1

(works only locally. Need to be updated to work correctly via tramp)

A little bit extended Burton's answer:

(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)) )) ) ) 

Comments

0

Ugh. Perhaps you could open a shell in Emacs and exec sudo emacs.

The problem is that you presumably don't just want to open the file. You want to be able to save it later. Thus you need your root privs to persist, not just exist for opening the file.

Sounds like you want Emacs to become your window manager. It's bloated enough without that. :)

6 Comments

Ha ha you said bloat. Emacs used to seem huge. Now, in comparison to run-time footprints of Java, Ruby, and probably a pile of other stuff, it looks quite lean. Regardless, I think Chris' question gets at a perfectly legitimate use of Emacs.
You beat me to it. I use this model consistently. At login I start one Emacs session for general stuff, one for SU access (as root) and one or more for software development (generally per-project but not always). Been doing it for years. Just works.
can you clarify how to do this: "open a shell in Emacs and exec sudo emacs"
@OpenLearner Seriously, you don't really want to do that.
You COULD upgrade the answer with a new, more modern solution. Where you basically write why the old solution isn't that great (which was awful even back then, when we do look at it through our security googles on). Back then there also was AngeFTP, if you would like a mode that was available back then. And what I can see, Tramp is dated back to 1999, but I can be at fault there.
|
0

I find sudo edit function very useful for that. After opening a file, press s-e to have sudo access to edit/save the file.

2 Comments

I don't have a super key. Which function does s-e invoke?
sudo-edit function is invoked.
0

In this blog post Bozhidar Batsov explains three easy methods for opening files with escalated permissions. I think the most elegant one is the following. I just did a minor modification to make it more compatible with Emacs default ecosystem so that it can automatically Vertico and other completion platforms:

(defun er-sudo-edit (&optional arg) "Edit currently visited file as root. With a prefix ARG prompt for a file to visit. Will also prompt for a file to visit if current buffer is not visiting a file." (interactive "P") (if (or arg (not buffer-file-name)) (find-file (concat "/sudo:root@localhost:" (read-file-name "Find file(as root): "))) (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))) 

Comments

0

A very convenient function for this is implemented in Bozhidar Batsov's excellent crux package.

https://github.com/bbatsov/crux

After installing (from melpa or melpa-stable) use crux-sudo-edit. Also useful is crux-reopen-as-root.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.