Vim: Salvar read only
Hoje, após um bom tempo editando o arquivo de configuração do Apache (/etc/httpd/httpd.conf
),
percebi que estava logado como usuário normal e não poderia salvar o arquivo
(E212: Can't open file for writing
).
Uma solução comum é salvar uma cópia em um diretório qualquer e depois substituir o arquivo original
pela cópia usando sudo mv
. Mas eu sabia que existe um jeito mais simples, pois isso já aconteceu
várias vezes no passado.
Eu tinha esquecido o comando, mas consegui encontrá-lo e vou deixar registrado aqui para consultas futuras.
Basta chamar sudo tee
direto do vim: :w !sudo tee %
O Vim vai avisar (W12
) que o arquivo foi modificado e deve ser recarregado. Pressione L
para
recarregar.
Por que funciona?
Do arquivo :help
do vim e man tee
, temos:
:w[rite] {file}
⇒ Escreve todo o buffer em {file}.!{cmd}
⇒ Executa {cmd} com o shell.tee [FILE]
⇒ Lê da standard input e escreve em FILE (ou stdout).%
⇒ Referência ao arquivo atual
Ou seja, jogamos o buffer como se fosse um pipe para a entrada de sudo tee %
, que escreve esse
buffer no arquivo atual, mas como super usuário.
Algumas alternativas que encontrei no commandlinefu:
:%!sudo tee %
:w !sudo tee > /dev/null %
command W :execute ':silent w !sudo tee % > /dev/null' | :edit!
:w !pfexec tee %
Neovim
(Sessão adicionada em março de 2024)
A dica anterior não funciona no Neovim (ver https://github.com/neovim/neovim/issues/1716).
Felizmente, existem plugins que resolvem esse problema. Eu uso o Suda: https://github.com/lambdalisue/suda.vim.
Ele adiciona os comandos :SudaWrite
e :SudaRead
para escrever e ler arquivos que precisam de
permissões elevadas.