Vim: Save read only
Today, after a long time editing the Apache configuration file (/etc/httpd/httpd.conf), I realized
that I was logged in as a normal user and couldn’t save the file
(E212: Can't open file for writing).
A common solution is to save a copy in any directory and then replace the original file with the
copy using sudo mv. But I knew there was a simpler way because this had happened several times in
the past.
I had forgotten the command, but I managed to find it and I will leave it documented here for future reference.
Just call sudo tee directly from vim: :w !sudo tee %
Vim will warn (W12) that the file has been modified and needs to be reloaded. Press L to reload.
Why does it work?
From the :help file of vim and man tee, we have:
:w[rite] {file}⇒ Writes the entire buffer to {file}.!{cmd}⇒ Executes {cmd} with the shell.tee [FILE]⇒ Reads from standard input and writes to FILE (or stdout).%⇒ Reference to the current file
In other words, we send the buffer as if it were a pipe to the input of sudo tee %, which writes
this buffer to the current file, but as a superuser.
Some alternatives I found on commandlinefu:
:%!sudo tee %:w !sudo tee > /dev/null %command W :execute ':silent w !sudo tee % > /dev/null' | :edit!:w !pfexec tee %
Neovim
(Session added in March 2024)
The previous tip does not work in Neovim (see https://github.com/neovim/neovim/issues/1716).
Fortunately, there are plugins that solve this problem. I use Suda: https://github.com/lambdalisue/suda.vim.
It adds the commands :SudaWrite and :SudaRead to write and read files that require elevated
permissions.