Obtendo permissões de root em um arquivo dentro do vi?

votos
227

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

sudo vi filename

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

Publicado 04/08/2008 em 04:34
fonte usuário
Em outras línguas...                            


11 respostas

votos
276

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

:w !sudo tee %

( vimIrá detectar que o arquivo foi alterado e perguntar se você quer que ele seja recarregado.)

Como um atalho, você pode definir o seu próprio comando. Coloque o seguinte em 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 mais agradável (na minha opinião) para fazer isso:

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

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

Respondeu 31/08/2008 em 20:23
fonte usuário

votos
29

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

:w !sudo tee myfile
Respondeu 04/08/2008 em 07:52
fonte usuário

votos
13

Advertências comuns

O método mais comum de se locomover o problema arquivo somente leitura é abrir um tubo para o arquivo atual como o super usuário usando uma implementação sudo tee. No entanto, todas as soluções mais populares que eu encontrei em torno da Internet têm uma combinação de várias advertências potenciais:

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

soluções

Para contornar todos esses problemas, 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 abreviados, 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ê precisará digitar este 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 continueprompt de -como que aparece após a execução do :!comando.

exec[ute]executa uma cadeia como um comando. Não podemos simplesmente executar :write, porque não vai processar a chamada função necessária.

!representa o :!comando: o único comando que :writeaceita. Normalmente, :writeaceita um caminho de arquivo para o qual escrever. :!em seu próprio executa um comando em um shell (por exemplo, usando bash -c). Com :write, ele será executado o comando no shell e, em seguida, escrever o arquivo inteiro para stdin.

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

teetubos stdinpara o arquivo fornecido. :writevai escrever para stdin, em seguida, o super-usuário teereceberá o conteúdo do arquivo e gravar o arquivo. Não vai criar um novo arquivo - basta substituir o conteúdo - assim modos de arquivo e atributos serão preservados.

shellescape()Escapa caracteres especiais no caminho de arquivo como apropriado para o shell atual. Com apenas um parâmetro, seria normalmente apenas coloque o caminho entre aspas, se necessário. Uma vez que estamos enviando para uma linha de comandos shell completo, vamos querer passar um valor diferente de zero como o segundo argumento para permitir a barra invertida-escaping de outros caracteres especiais que poderiam viagem até o shell.

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

>NULe >/dev/nullredirecionar stdoutpara dispositivo nulo da plataforma. Mesmo que nós silenciou o comando, nós não queremos que todos a sobrecarga associada à tubulação stdinde volta para vim - melhor para despejá-lo o mais cedo possível. NULé o dispositivo nulo em DOS, MS-DOS e Windows, não é um arquivo válido. Como do Windows 8 redirecionamentos para NUL não resultam em um arquivo chamado NUL sendo escrito. Tente criar um arquivo em seu desktop chamado NUL, com ou sem uma extensão de arquivo: você não será capaz de fazê-lo. (Existem vários outros nomes de dispositivos no Windows que podem ser vale a pena conhecer.)

~ / Vimrc

Platform-Dependent

Claro, você ainda não quiser memorizar os e digite-os cada vez. É muito mais fácil para mapear o comando apropriado para um comando mais simples usuário. Para fazer isso em POSIX, você pode adicionar a seguinte linha ao seu ~/.vimrcarquivo, criando-lo se ele ainda não existir:

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

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

Plataforma independente

Eu uso uma plataforma independente de ~/.vimrcarquivo que sincroniza entre computadores, então eu adicionei funcionalidade multi-plataforma para o meu. Aqui está uma ~/.vimrcapenas com as configuraçõ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
Respondeu 13/10/2012 em 07:54
fonte usuário

votos
10

Se você estiver usando Vim , existe um script disponível chamado sudo.vim . Se você achar que você abriu um arquivo que você precisa de acesso root para ler, tipo

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

Respondeu 24/09/2008 em 05:12
fonte usuário

votos
7

O conselho de Ryan é geralmente boa, no entanto, se seguir o passo 3, não mover o arquivo temporário; ele vai ter a propriedade errada e permissões. Em vez disso, sudoedito arquivo correto e ler no conteúdo (usando :rou afins) do arquivo temporário.

Se seguir o passo 2, use :w!para forçar o arquivo a ser gravado.

Respondeu 04/08/2008 em 05:04
fonte usuário

votos
3

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

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

Se eu perder isso, 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 uma maneira menos rotunda para fazê-lo, mas ele funciona.

Respondeu 12/08/2008 em 19:37
fonte usuário

votos
1

Aqui está mais um que tem aparecido uma vez que esta pergunta foi respondida, um plugin chamado SudoEdit que fornece funções SudoRead e SudoWrite, que, por padrão, tente usar sudo primeira e su se isso falhar: http://www.vim.org/scripts/ script.php? SCRIPT_ID = 2709

Respondeu 29/01/2010 em 18:21
fonte usuário

votos
1

Uma rápida Google parece dar este conselho:

  1. Não tente editar se for somente leitura.
  2. Você pode ser capaz de alterar as permissões sobre o arquivo. (Se é ou não vai deixar você guardar cabe a experimentação.)
  3. Se você ainda editado de qualquer forma, salvar em um arquivo temporário e, em seguida, movê-lo.

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

Respondeu 04/08/2008 em 04:39
fonte usuário

votos
0

Eu tenho isso no meu ~ / .bashrc:

alias svim='sudo vim'

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

Respondeu 19/03/2009 em 13:51
fonte usuário

votos
-2

Um corte rápido você pode considerar está fazendo um chmod no arquivo que você está editando, salvar com o vim, e depois chmod volta para o 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 essa abordagem em um sistema onde você está preocupado com a segurança, como por alguns segundos qualquer pessoa pode ler / alterar o arquivo sem você perceber.

Respondeu 05/08/2008 em 23:20
fonte usuário

votos
-7

usar gksudo em vez de sudo para GVim ou seja

cmap w!! w !gksudo tee >/dev/null %
Respondeu 30/11/2010 em 07:33
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more