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.