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.


Julio Batista Silva
Julio Batista Silva
Engenheiro de Dados

Eu sou um engenheiro de computação apaixonado por ciência, tecnologia, fotografia e idiomas. Atualmente trabalhando como Engenheiro de Dados na Alemanha.

comments powered by Disqus