Pergunta

Muitas vezes, durante a edição de arquivos de configuração, eu vou abrir um com o vi e depois, quando eu ir para salvá-lo perceber que eu não o tipo de

sudo vi filename

Existe alguma maneira de dar sudo vi privilégios para salvar o arquivo?Eu me lembro de ter visto algo sobre isso enquanto procurando algumas coisas sobre o vi há um tempo atrás, mas agora eu não posso encontrá-lo.

Foi útil?

Solução

% é substituído com o nome do arquivo atual, assim você pode usar:

:w !sudo tee %

(vim irá detectar que o arquivo foi alterado e perguntar se você deseja ser recarregado.Dizer sim ao escolher [L] em vez de OK.)

Como um atalho, você pode definir o seu próprio comando.Colocar o seguinte no seu .vimrc:

command W w !sudo tee % >/dev/null

Com o acima, você pode digitar :W<Enter> para salvar o arquivo.Desde que eu escrevi isso, eu encontrei uma maneira melhor (na minha opinião) para fazer isso:

cmap w!! w !sudo tee >/dev/null %

Desta forma, você pode digitar :w!! e ele será expandido para a linha de comando completa, deixando o cursor no final, então você pode substituir o % com um nome de arquivo de seu próprio, se você gosta.

Outras dicas

Em geral, você não pode alterar o id de usuário efetivo do vi processo, mas você pode fazer isso:

:w !sudo tee myfile

Comum Advertências

O método mais comum de contornar o arquivo somente-leitura problema é que para abrir um pipe para o arquivo atual como a de um super-utilizador usando uma implementação de sudo tee.No entanto, todos os mais populares soluções que tenho encontrado na Internet têm uma combinação de vários possíveis advertências:

  • Todo o arquivo é gravado para o terminal, bem como o arquivo.Isso pode ser lento para arquivos grandes, especialmente em conexões de rede lentas.
  • O arquivo perde seus modos e atributos semelhantes.
  • Caminhos de arquivo com caracteres especiais ou espaços não podem ser manipulados corretamente.

Soluções

Para chegar em torno de todas estas questões, você pode usar o seguinte comando:

" On POSIX (Linux/Mac/BSD):
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

" Depending on the implementation, you might need this on Windows:
:silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >NUL'

Estes podem ser reduzidos, respeitosamente:

:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'
:sil exec 'w !sudo tee ' . shellescape(@%, 1) . ' >NUL'

Explicação

: começa o comando;você vai precisar para esse tipo de personagem no modo normal para começar a introduzir um comando.Ele deve ser omitido em scripts.

sil[ent] suprime a saída do comando.Neste caso, queremos parar o Press any key to continue-como prompt que aparece depois de executar o :! de comando.

exec[ute] executa uma seqüência de caracteres como um comando.Não podemos simplesmente executar :write porque ele não vai processar o necessário chamada de função.

! representa o :! comando:o único comando que :write aceita.Normalmente, :write aceita um caminho de arquivo para o qual escrever. :! em sua própria executa um comando em um shell (por exemplo, usando bash -c).Com :write, ele vai executar o seguinte comando no shell e, em seguida, gravar o arquivo inteiro para stdin.

sudo deve ser óbvio, já que é por isso que você está aqui.Execute o comando como super-usuário.Há uma abundância de informações em torno do 'net sobre como isso funciona.

tee tubos stdin a um dado arquivo. :write vai escrever para stdin, e , em seguida, o super-usuário tee irá receber o conteúdo do arquivo e gravar o arquivo.Ele não vai criar um novo arquivo--apenas substituir o conteúdo--então, arquivo e modos de atributos serão preservados.

shellescape() escapa caracteres especiais em um determinado caminho de arquivo apropriado para o shell atual.Com apenas um parâmetro, que normalmente seriam apenas colocar o caminho entre aspas, conforme necessário.Desde que nós estamos enviando para uma completa linha de comando do shell, vamos querer passar um valor diferente de zero como o segundo argumento para habilitar a barra invertida escapar de outros caracteres especiais que poderiam viagem até o shell.

@% lê o conteúdo do % registrar, que contém o buffer atual do nome do arquivo.Ele não é necessariamente um caminho absoluto, de modo a assegurar que você não tiver alterado o diretório atual.Em algumas soluções, você vai ver o comercial-símbolo omitido.Dependendo da localização, % é uma expressão válida, e tem o mesmo efeito que a leitura do % registrar.Aninhada dentro de outra expressão, o atalho é geralmente permitido, no entanto:tal como no presente caso.

>NUL e >/dev/null redirecionar stdout para a plataforma de dispositivo nulo.Apesar de nós já calaram o comando, não queremos todos a sobrecarga associada com a tubulação stdin de volta para vim--melhor para despejá-lo o mais cedo possível. NUL é o dispositivo nulo no ms-DOS, MS-DOS e Windows, não é um arquivo válido.Como o Windows 8 redirecionamentos para NUL não resultar em um arquivo chamado NUL a ser escrito.Tente criar um arquivo no seu desktop com o nome NUL, com ou sem uma extensão de arquivo:você vai ser incapaz de fazê-lo.(Há vários outros nomes de dispositivos no Windows que pode valer a pena conhecer.)

~/.vimrc

Dependente De Plataforma

Claro, você ainda não quer memorizar os e escreva-os para fora, de cada vez.É muito mais fácil para mapear o comando apropriado para um usuário mais simples do comando.Para fazer isso no POSIX, você pode adicionar a seguinte linha ao seu ~/.vimrc arquivo, criando-o se ainda não existir:

command W silent execute 'write !sudo tee ' . shellescape(@%, 1) . ' >/dev/null'

Isto irá permitir que você digite a :W (sensível a maiúsculas e minúsculas) comando para gravar o arquivo atual com o super-usuário permissões, muito mais fácil.

Independente De Plataforma

Eu uso uma plataforma independente ~/.vimrc arquivo que sincroniza através de computadores, então eu adicionei multi-funcionalidade da plataforma para a minha.Aqui está um ~/.vimrc com apenas definições relevantes:

#!vim
" Use za (not a command; the keys) in normal mode to toggle a fold.
" META_COMMENT Modeline Definition: {{{1
" vim: ts=4 sw=4 sr sts=4 fdm=marker ff=unix fenc=utf-8
"   ts:     Actual tab character stops.
"   sw:     Indentation commands shift by this much.
"   sr:     Round existing indentation when using shift commands.
"   sts:    Virtual tab stops while using tab key.
"   fdm:    Folds are manually defined in file syntax.
"   ff:     Line endings should always be <NL> (line feed #09).
"   fenc:   Should always be UTF-8; #! must be first bytes, so no BOM.


" General Commands: User Ex commands. {{{1
    command W call WriteAsSuperUser(@%)         " Write file as super-user.


" Helper Functions: Used by user Ex commands. {{{1
    function GetNullDevice() " Gets the path to the null device. {{{2
        if filewritable('/dev/null')
            return '/dev/null'
        else
            return 'NUL'
        endif
    endfunction

    function WriteAsSuperUser(file) " Write buffer to a:file as the super user (on POSIX, root). {{{2
        exec '%write !sudo tee ' . shellescape(a:file, 1) . ' >' . GetNullDevice()
    endfunction


" }}}1
" EOF

Se você estiver usando Vim, existe um script chamado disponível o sudo.vim.Se você achar que você abriu um arquivo que você necessitará ter acesso root ao ler, digite

:e sudo:%
Vim substitui o % com o nome do arquivo atual, e sudo: instrui o comando sudo.vim de script para a leitura e a escrita.

Ryan conselho é geralmente boa, no entanto, se seguir o passo 3, não mova o arquivo temporário;ele vai ter errado a propriedade e as permissões.Em vez disso, sudoedit o arquivo correto e ler o conteúdo (usando :r ou algo assim) do arquivo temporário.

Se, após a etapa 2, use :w! para forçar o arquivo a ser gravado.

Quando você entra em modo de inserção em um arquivo, você precisa sudo acesso para editar, você receber uma mensagem de status dizendo:

-- INSERT -- W10: Warning: Changing a readonly file

Se eu esquecer de que, geralmente eu faço

:w ~/edited_blah.tmp
:q

..então..

sudo "cat edited_blah.tmp > /etc/blah"

..ou..

sudo mv edited_blah.tmp /etc/blah

Há provavelmente menos rotunda forma de o fazer, mas funciona.

Uma rápida no Google parece dar este conselho:

  1. Não tente editar se é só de leitura.
  2. Você pode ser capaz de alterar as permissões do arquivo.(Se ele irá ou não permitir que você salve é à experimentação.)
  3. Se você ainda editado de qualquer maneira, salvar em um arquivo temporário e, em seguida, movê-lo.

http://ubuntuforums.org/showthread.php?t=782136

Aqui está mais um que apareceu desde a esta pergunta foi respondida, um plugin chamado SudoEdit que fornece SudoRead e SudoWrite funções, o que irá, por padrão, tente utilizar o sudo primeiro e su se isso falhar: http://www.vim.org/scripts/script.php?script_id=2709

Eu tenho isso no meu ~/.bashrc:

alias svim='sudo vim'

Agora sempre que eu precisar editar um arquivo de configuração eu apenas abri-lo com svim.

Um pequeno truque que você pode considerar é fazer um chmod no arquivo que você está editando, salve com o vim, e, em seguida, chmod para trás para que o arquivo foi originalmente.

ls -l test.file (to see the permissions of the file)
chmod 777 test.file
[This is where you save in vim]
chmod xxx test.file (restore the permissions you found in the first step)

É claro que eu não recomendo esta abordagem em um sistema onde você estiver preocupado com a segurança, como por alguns segundos, qualquer um pode ler/alterar o arquivo sem você perceber.

utilização gksudo em vez de sudo para o GVim i.e.

cmap w!! w !gksudo tee >/dev/null %
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top