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.
: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.
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.
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.
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.
What I normally do - not necessarily the quickest, but certainly safe - is to do something like this (using nsswitch.conf as example):
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.