Last Updated: February 25, 2016
·
1.252K
· lee-jon

Vim: save without sudo

TL;DR

If you've edited a file in vim and you don't have write permission you can save the file using:

:w !sudo tee %

How it works

Confusingly, this doesn't work by giving you sudo access to the file. :w makes it look that way, as most people think of this as 'save' or 'save as' when specified with a file name. Instead the output from :w is redirected to a shell command tee with sudo privileges.

% references the current file. You see this in :s%/foo/FOO which searches (s) the current file (%) for foo and replaces with FOO. This is used as the parameter for tee to overwrite the file.

The tee command is used as a hack. Tee is effectively a t-shaped junction for UNIX pipes. Tee takes the output from the previous command and sends it in two directions. This is normally a file, and sending along the pipe to another command. For example, the following command will take crontab entries, tee creates a backup file and then passes the files to sed for substitution, before relaunching crontab:

$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab –

In this tip, tee takes the working file as input, and saves a copy to on top of the working file (%). There is no following command so it is just echoed (you could send this to nothing by inserting "> /dev/null" before the %, if you're that much of a purist!

Why use tee and ignore half the output, rather than something linear like cat?

The benefit of tee is that sudo is applied to the command and obviously its parameters.

:w !sudo cat > %

will not work because sudo is applied to cat, not to the redirection > so overwriting the file will fail.

Reload!

Oh, and VIM will request a reload, because something else (tee) has changed the file.

Thanks to 101hacks.com for the tee example.