¿Cómo guardar un archivo para el que no tengo permisos de escritura?

26

A veces sucede que abro un archivo y hago algunas modificaciones como mi propio usuario, sin darme cuenta u "olvidarme" de notar la [read-only]advertencia en la línea de estado (es decir, algún /etcarchivo de configuración aleatorio como /etc/resolv.conf).

:w!obviamente falla en este caso porque mi usuario no tiene permiso de escritura de todos modos. Así que tengo que :w /home/filenamesalir y sudo mv ..., muy incómodo.

¿Hay alguna manera de que escale temporalmente a root para poder guardar el archivo abierto actualmente? (dado que estoy en sudoers/ y puedo sudirectamente)?

guido
fuente

Respuestas:

24

El truco es usar una llamada externa para sudo:

:w !sudo tee %

Cómo funciona esto:

  • :w !<command>se ejecuta <command>con el contenido del búfer como stdin.
  • teeduplica stdin a un archivo & stdout; %se expande al nombre de archivo actual ..
  • Prefijo esto con sudopermisos de root.

Realmente no está guardando el archivo con Vim, sino que está llamando a un programa externo para sobrescribir el contenido del archivo que está editando. Es por eso que recibirá una advertencia de 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: 

Podrías convertir esto en una función:

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

Y keybind:

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

Con su, solo el usuario root puede usar -cpara ejecutar inmediatamente un comando. No creo que puedas usarlo supara hacer esto, pero quizás hay un truco del que no estoy al tanto ...

Martin Tournoij
fuente
SuperWritefunciona, pero te devuelve el archivo. Al ejecutarlo, :silentdebe ingresar su contraseña de manera invisible.
TankorSmash
@TankorSmash Gracias; respuesta actualizada Sin embargo, ¿no estás seguro de lo que quieres decir con "ingresa tu contraseña de manera invisible"? ¿Agregar silentparece funcionar bien?
Martin Tournoij
No ejecuto vim con sudo, por lo que puede estar en juego aquí, pero cuando voy a sudo tee el archivo, me pide la contraseña de sudo. Si está en silencio, no veo el mensaje, pero todavía necesito ingresar una contraseña.
TankorSmash
1
Lo que está viendo es la funcionalidad estándar de tee de eco a stdout, así como el archivo proporcionado. Una solución es redirigir stdout a / dev / null, a la: w ! tee % > /dev/null Esto aún reflejará el resultado del comando (una sola línea), pero no todo el contenido del búfer.
Jon Carter
En lugar de usar y teeluego desechar su salida, ¿no catfuncionaría también si no desea imprimir el archivo?
Lie Ryan
12

Utilizo la siguiente asignación en mi .vimrc, que me parece útil:

cnoremap w!! w !sudo tee %

Es fácil de recordar, porque wes "escritura", w!es "escritura forzada" y w!!es "escritura super-duper-force". :PAGS

Perilla de la puerta
fuente
1
Hace tiempo que lo he mapeado W, pero w!!tiene mucho más sentido, actualizaré mi .vimrc. Gracias
jalanb