FANDOM


(Remove html character entities)
(reword and merge in tip from 200810)
Line 1: Line 1:
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=975
 
|id=975
Line 12: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
I just wrote a little function that uses sudo and cp to save a file whose modes wouldn't allow me to write it.
+
Sometimes you modify a file, for example from the <tt>/etc</tt> directory, then when you try to save the file, you get a permission-denied error. This tip presents some suggestions for using sudo from with Vim, so you can successfullly write the file with temporary privileges.
   
Obviously, it preserves the modes of the original file, though it is being rewriten. Of course, this tip has to be used with real caution, as it gets you more power.
+
Of course, this tip has to be used with caution, as it gets you more power.
   
TODO:
+
==Suggestion 1==
*The only real drawback is there's no check for symlinks, and then, the symlink would get removed and replaced by a file with the symlink's modes, which are 777.
+
If you find you do not have permission to perform <tt>:w</tt>, use the following:
*Another thing that would be nice, would be to integrate it to the interface, to get it work when :w is not enough, or at least having an alias like :wforce, :w!! or :whatever.
+
<pre>
  +
:w !sudo tee % > /dev/null
  +
</pre>
   
  +
You can make a command so <tt>:W</tt> invokes sudo:
  +
<pre>
  +
command W w !sudo tee % > /dev/null
  +
</pre>
  +
  +
Or, if you know about the problem before starting Vim:
  +
<pre>
  +
sudo vim path_to_file
  +
</pre>
  +
  +
==Suggestion 2==
  +
The following function saves the current file to a temporary file, then copies the new file to replace the original. It preserves the modes of the original file, though it is being rewriten.
 
<pre>
 
<pre>
 
function Suedit()
 
function Suedit()
Line 32: Line 43:
 
</pre>
 
</pre>
   
==Comments==
+
'''Warning''' There is no check for symlinks. A symlink would be removed and replaced by a file with the symlink's modes, which are 777.
Just use:
 
   
  +
==Suggestion 3==
  +
Here is a mapping to save to a <tt>/tmp</tt> file, then overwrite the working file.
 
<pre>
 
<pre>
system('stat -c%a '.expand("%"))
+
nnoremap <leader>es :w! /tmp/sudoSave \| let $fileToSave=expand('%') \| let $fileToSaveBackup=expand('%').'~' \| !sudo cp $fileToSave $fileToSaveBackup && sudo cp /tmp/sudoSave $fileToSave<CR><ESC>:e!<CR>
instead of
 
system('find . -maxdepth 1 -name '.expand("%").' -printf "%m"')
 
 
</pre>
 
</pre>
   
----
+
'''Warning''' This command will reload the file; you will lose the modifications history (undo will not work, although it does keep a backup).
Use {{script|id=729}} which has had more testing.
 
   
----
+
Note that a backup is made, even when '<tt>nobackup</tt>' is set.
It's very simple:
 
   
<pre>
+
==Comments==
:w !sudo tee %
+
Use {{script|id=729}} which has had more testing.
</pre>
 
 
----
 
Minor improvement to prevent tee's stdout from "cluttering" your vim session:
 
 
<pre>
 
:w !sudo tee % > /dev/null
 
</pre>
 
 
But why not just:
 
 
<pre>
 
sudo vi <file_whose_modes_wouldn't_allow_me_to_write_it>
 
</pre>
 
   
 
----
 
----

Revision as of 08:18, April 6, 2009

Tip 975 Printable Monobook Previous Next

created August 18, 2005 · complexity basic · author Bernard Pratz · version 6.0


Sometimes you modify a file, for example from the /etc directory, then when you try to save the file, you get a permission-denied error. This tip presents some suggestions for using sudo from with Vim, so you can successfullly write the file with temporary privileges.

Of course, this tip has to be used with caution, as it gets you more power.

Suggestion 1

If you find you do not have permission to perform :w, use the following:

:w !sudo tee % > /dev/null

You can make a command so :W invokes sudo:

command W w !sudo tee % > /dev/null

Or, if you know about the problem before starting Vim:

sudo vim path_to_file

Suggestion 2

The following function saves the current file to a temporary file, then copies the new file to replace the original. It preserves the modes of the original file, though it is being rewriten.

function Suedit()
  let fname=tempname()
  exe 'w '.fname
  let owner=system('stat -c%U:%G '.expand("%"))
  let modes=system('stat -c%a '.expand("%"))
  exec '!sudo cp '.fname.' '.expand("%")
  exec '!sudo chmod '.modes." ".expand("%")
  exec '!sudo chown '.owner'" ".expand("%")
endfunction

Warning There is no check for symlinks. A symlink would be removed and replaced by a file with the symlink's modes, which are 777.

Suggestion 3

Here is a mapping to save to a /tmp file, then overwrite the working file.

nnoremap <leader>es :w! /tmp/sudoSave \| let $fileToSave=expand('%') \| let $fileToSaveBackup=expand('%').'~' \| !sudo cp $fileToSave $fileToSaveBackup && sudo cp /tmp/sudoSave $fileToSave<CR><ESC>:e!<CR>

Warning This command will reload the file; you will lose the modifications history (undo will not work, although it does keep a backup).

Note that a backup is made, even when 'nobackup' is set.

Comments

Use script#729 which has had more testing.


Community content is available under CC-BY-SA unless otherwise noted.