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.