¿Cómo funciona `: w! Sudo tee%`

27

Si abre un archivo en el que no tiene permiso para escribir en vim, luego decide que necesita cambiarlo, puede escribir sus cambios sin salir de vim haciendo :w !sudo tee %
No entiendo cómo puede funcionar esto. ¿Puedes por favor diseccionar esto?
Entiendo la :wparte, escribe el búfer actual en el disco, suponiendo que ya hay un nombre de archivo asociado, ¿verdad?
También entiendo el !que ejecuta el sudo teecomando y %representa el contenido actual del búfer, ¿verdad?
Pero aún no entiendo cómo funciona esto.

Ali
fuente

Respuestas:

30

La estructura :w !cmdsignifica "escribir el búfer actual canalizado a través del comando". Entonces puede hacerlo, por ejemplo, :w !caty canalizará el búfer cat.

Ahora %es el nombre de archivo asociado con el búfer

Así :w !sudo tee %se canalizará el contenido del búfer sudo tee FILENAME. Esto escribe efectivamente el contenido del búfer en el archivo.

Stephen Harris
fuente
Y lo que es tee?
CodyBugstein
7

% representa el nombre de archivo del búfer actual, no su contenido.

entonces :w !sudo tee %significa canalizar el buffer actual a sudo tee [currentfilename].

tee se ejecuta como root, por lo que tiene acceso de escritura para guardar su stdin en el archivo.

Ver también /programming/2600783/how-does-the-vim-write-with-sudo-trick-work

cas
fuente
2

¡No del todo bien!

!commandejecuta el comando como un comando de filtro , que obtiene texto stdin, hace algo y lo envía a stdout.

Mediante el uso w, que empujó el contenido del archivo a stdinde sudo tee %. %es un registro especial en vim, que contiene el nombre del archivo actual.

Entonces tienes sudo tee FILENAME, que empujará tee stdinel contenido del archivo al archivo actual.

Cuonglm
fuente
2
:!commandes un filtro (cf. :h !), mientras :w !commandque no lo es, solo se ejecuta commandcon el archivo actual como stdin(cf. :h :w_c). A saber: :w !sed /./dno cambia el contenido del búfer actual. Pero la receta es de hecho no está bien por otra razón, %necesita ser escapado: :exec 'w !sudo tee ' . shellescape(expand('%', 1)). El comando original no funciona con, por ejemplo, nombres de archivo con espacios.
Satō Katsura el