If you use Vim or Neovim, you've probably found that you can't save the modifications you've made to a file, because you don't have write permissions or the file doesn't belong to you.
The simplest solution is to remember to use
sudo before editing a file
that you don't have permission to edit (usually system configuration
files). But when you have already forgotten to use
sudo and you have
made many modifications, the following trick will save you time and
The first thing to do is to analyse the situation. If the editor won't
let us save the file, it's because we don't have permission to modify
it. We can try, by running
:w!, but if the file belongs to another
user and we don't have write permissions, it won't work.
If it has let us read the contents of the file, what we can do is save
it under a different filename. In Vim we can do this by running
other_filename. But this solution is not entirely satisfactory, as we
would have to run a new command to replace the file we are editing:
!sudo mv other_filename %1.
There is a simpler way to achieve our goal: using the
:w !sudo dd of=%. This instruction works as follows:
:w !. As the Vim documentation (
:h w_c) explains, statements following the exclamation mark are executed by taking the contents of the buffer (i.e. the file) as standard input.
sudoallows us to execute the command with superuser permissions.
dd of=%takes the standard input and writes its contents to the file we are editing.
After executing the above command, we must enter our password. Then Vim will warn us that the file has changed and that the buffer has been modified as well. Simply press O and then press Enter to continue.
This trick can be difficult to remember, so it is a good idea to add the following line to the Vim configuration file:
cmap w!! w !sudo dd of=%<Enter>
With it, you only need to run
:w!! the next time you have this
%is equivalent to writing the path to the file you are editing (run
:h %for more information). The
!at the beginning of the command tells Vim to execute a command using the system shell (run
:h :!for more information). ↩