Como salvar um arquivo para o qual não tenho permissões de gravação?

26

Às vezes acontece que eu abro um arquivo e faço algumas modificações como meu próprio usuário, sem perceber ou "esquecer" de perceber o [read-only]aviso na linha de status (ou seja, algum /etcarquivo de configuração aleatório como /etc/resolv.conf).

:w!obviamente falha nesse caso, porque meu usuário não tem permissão de gravação. Então eu tenho que :w /home/filenamesair e sudo mv ..., muito desconfortável.

Existe uma maneira de escalar temporariamente para o root para poder salvar o arquivo aberto no momento? (dado que estou sudoersou posso sudiretamente)?

guido
fonte

Respostas:

24

O truque é usar uma chamada externa para sudo:

:w !sudo tee %

Como isso funciona:

  • :w !<command>executa <command>com o conteúdo do buffer como stdin.
  • teeduplica o stdin para um arquivo & stdout; %expande para o nome do arquivo atual ..
  • Você prefixa isso com sudopermissões de raiz.

Você não está realmente salvando o arquivo com o Vim; está chamando um programa externo para substituir o conteúdo do arquivo que está editando. É por isso que você receberá um aviso do Vim:

W12: Warning: File "xxx" has changed and the buffer was changed in Vim as well
See ":help W12" for more info.
[O]K, (L)oad File: 

Você pode transformar isso em uma função:

fun! SuperWrite()
        write !sudo tee %
        " Or with :silent (but that doesn't seem to work for everyone)
        "silent write !sudo tee %
        edit!
endfun

E keybind:

nnoremap <Leader>w! :call SuperWrite()<CR>

Com su, apenas o usuário root pode usar -cpara executar imediatamente um comando. Eu não acho que você possa usar suisso, mas talvez haja um truque que eu não conheça ...

Martin Tournoij
fonte
SuperWritefunciona, mas faz eco do arquivo de volta para você. Ao :silentexecutá- lo , você deve digitar sua senha invisivelmente.
TankorSmash 23/02
@TankorSmash Thanks; resposta atualizada. Não sabe o que você quer dizer com "digite sua senha invisivelmente"? Adicionando silentparece funcionar bem?
Martin Tournoij 23/02
Eu não corro o vim com o sudo, então isso pode estar em jogo aqui, mas quando vou ao sudo tee do arquivo, ele me solicita a senha do sudo. Se estiver silencioso, não vejo o prompt, mas ainda preciso inserir uma senha.
TankorSmash
11
O que você está vendo é a funcionalidade padrão do tee de eco para stdout, bem como o arquivo fornecido. Uma solução é redirecionar stdout para / dev / null, à la: w ! tee % > /dev/null Isso ainda ecoará o resultado do comando (uma única linha), mas não o conteúdo inteiro do buffer.
Jon Carter
Em vez de usar e teedepois jogar fora sua saída, cattambém não funcionaria se você não quiser que o arquivo seja impresso?
Lie Ryan
12

Eu uso o seguinte mapeamento no meu .vimrc, que acho útil:

cnoremap w!! w !sudo tee %

É fácil lembrar, porque wé "escrever", w!é "escrever com força" e "escrever com força w!!super-duper". : P

Maçaneta
fonte
11
Há muito tempo que ele foi mapeado W, mas w!!faz muito mais sentido, deve atualizar meu .vimrc. Obrigado
jalanb