29

I often open a file in vim, make some changes and when it's time to save the file is read-only.. (owned by another user). I'm looking for tips on how I could re-open the file as root and keep my changes without first saving it to a temporary file for copy or re-edit as root.

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
rkthkr
  • 8,503
  • 26
  • 38

4 Answers4

44

From this stackoverflow answer, by skinp

:w !sudo tee %

I often forget to sudo before editing a file I don't have write permissions on. When I come to save that file and get a permission error, I just issue that vim command in order to save the file without the need to save it to a temp file and then copy it back again.

dbr
  • 1,538
  • 3
  • 16
  • 18
  • That is almost it.. But it would be nice to have vim restarted and run as root.. This is my favorite so far :) – rkthkr Jun 09 '09 at 13:44
  • @rkthkr, if "vim restarted and run as root" you would be unable to save any edits you have made, and lose your undo history. But if that is what you want... [Ran out of characters.] See the "answer" I'm about to write. – Bruno Bronosky Jun 16 '09 at 04:15
  • 3
    @dbr, I think it is worth mentioning that after you overwrite the file (with tee as sudo), you will get prompted with [O]k or [L]oad. The later option will erase your undo history an reset the "modified flag" allowing you to exit without being warned to save changes. The former option, which I prefer, will preserve your undo history, but will cause you to get warned when you try to quit. You have to use :q! to quit in this case. I do this so I can validate (e.g. :!sudo /etc/init.d/httpd configtest) and rollback/reedit if I need to. – Bruno Bronosky Jun 16 '09 at 04:26
17

Please do not vote me down for this. I do not recommend implementing this answer, but it is the answer that the rkthkr is asking for.

rkthkr said:
But it would be nice to have vim restarted and run as root

The way to do this is with :!sudo vim %
As I mentioned to ipozgaj, a % as an argument (even a sub-argument) gets replaced with the path to the current buffer. (You may get prompted for your password.) You end up with a new vim process, owned by root, that is a child process of the original vim process. Sounds goofy, right? Here is what it looks like in ps:

~# ps afo pid,ppid,user,stat,comm
  PID  PPID USER         STAT COMMAND
16187 30478 rbronosky    Ss   bash
16510 16187 rbronosky    R+    \_ ps
30482 30478 rbronosky    Ss   bash
16244 30482 rbronosky    S+    \_ vim
16318 16244 root         S+        \_ vim

If you have write permissions to the directory that contains the file and you have made edits to it, you may get warned that a swap file exits. Choosing to [R]ecover, will reflect most* of the changes made by the parent vim process. (*I think maybe the swap update is timed or has a delta threshold. I've put too much time into this already and do not care to research it.) When you go and quit vim, don't be alarmed when you are still in vim... you opened a 2nd vim process. Remember?

Now, with all of that said... I would almost never do this. Maybe, if I have had not enough or way too much coffee, and I realized that I was going to need to edit several more files as root... I might try this. In 14 years of administering systems, I never have. But, until you expressed discontent with my preferred solution (which is exactly as dbr offered) I had never thought about this.

Bruno Bronosky
  • 4,429
  • 3
  • 24
  • 32
1

I usually save it to a temporary file in $HOME/tmp/apache.conf (for example) then

sudo vimdiff $HOME/tmp/apache.conf /etc/apache2/apache.conf

this is some extra work to merge the changes but it paid off. I find it to be a nice way between convenience and measurements against unwanted changes

Before that I was thinking of ACLs or assigning corresponding groups to the files but it didn't work out all to often I either forgot to change the ownerships or was changing files where I didn't mean to do so.

That goes only for files which aren't managed until now. The overall solution we use is puppet with a git repo where people locally edit files and test the changes on appropriate servers, if the configuration works as desired the changes are pushed back to the central repository where our configuration engine pulls changes at regular intervalls.

Martin M.
  • 6,428
  • 2
  • 24
  • 42
0

What I normally do - not necessarily the quickest, but certainly safe - is to do something like this (using nsswitch.conf as example):

:w! ~/%

Exit from vim, then do:

sudo vim nsswitch.conf
1GdG
:r ~/%

This will delete all of the lines and read in your changed and updated version to be edited in its place. Using your home directory means you don't have to think about whether you have access or not - and its more private than /tmp. Note well that this is a whole file replacement: if you don't want to add all the changes, you'll have to pick and choose.

In spite of the headache involved in any of these answers, there's no reason to lose your changes.

Mei
  • 4,560
  • 8
  • 44
  • 53