A obtenção de permissões de root em um arquivo dentro do vi?
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.
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:
- Não tente editar se é só de leitura.
- Você pode ser capaz de alterar as permissões do arquivo.(Se ele irá ou não permitir que você salve é à experimentação.)
- Se você ainda editado de qualquer maneira, salvar em um arquivo temporário e, em seguida, movê-lo.
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 %