How does `:w !sudo tee %` work

12,820

Solution 1

The structure :w !cmd means "write the current buffer piped through command". So you can do, for example :w !cat and it will pipe the buffer through cat.

Now % is the filename associated with the buffer

So :w !sudo tee % will pipe the contents of the buffer through sudo tee FILENAME. This effectively writes the contents of the buffer out to the file.

Solution 2

% represents the current buffer's filename, not its contents.

so :w !sudo tee % means pipe the current buffer to sudo tee [currentfilename].

tee is being run as root, so has write access to save its stdin to the file.

See also https://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work

Solution 3

Not quite right!

!command runs command as a filter command, which get text from stdin, do something and output to stdout.

By using w, you pushed file content to stdin of sudo tee %. % is special register in vim, which holds the name of current file.

So you got sudo tee FILENAME, which will push tee stdin - file content - to current file.

Share:
12,820

Related videos on Youtube

Ali
Author by

Ali

I love to build things that people love to use. I like scientific data analysis. I've spent most of my life in medicine and neuroscience! I like: vim, zsh, golang, debian, python I am addicted to writing code! and learning new things!!

Updated on September 18, 2022

Comments

  • Ali
    Ali over 1 year

    If you open a file that you don't have permission to write to in vim, then decide you need to change it, you can write your changes without exiting vim by doing :w !sudo tee %
    I don't understand how this can work. Can you please dissect this?
    I understand the :w part, it writes the current buffer to disk, assuming there already is a file name associated with it, right?
    I also understand the ! which executes the sudo tee command and % represents the current buffer content right?
    But still don't understand how this works.

  • Satō Katsura
    Satō Katsura over 7 years
    :!command is a filter (cf. :h !), while :w !command is not, it just executes command with the current file as stdin (cf. :h :w_c). To wit: :w !sed /./d doesn't change the content of the current buffer. But the recipe is indeed not quite right for another reason, % needs to be escaped: :exec 'w !sudo tee ' . shellescape(expand('%', 1)). The original command doesn't work with, say, filenames with spaces.
  • user3426706
    user3426706 over 4 years
    And what is tee?
  • jalanb
    jalanb almost 3 years
    tee is a Linux command used to split streams, like a "T-splitter" in plumbing. More info at Wikipedia: en.wikipedia.org/wiki/Tee_(command)