Wonderful! I could have done with this trick the number of times I've been caught out with this one. Noted with thanks.

20+ years of using Unix and vi, and still learning tricks. Love it!

The quotes around the percent sign are unnecessary. The command `:w !sudo tee %` works just fine. I use it everytime!

LP,

Like I explained in my blog post, the quotes around the percent sign are necessary to keep the filename as a single argument when the filename contains whitespace. If there is no whitespace in the filename, then the quotes are not necessary.

Here is an experiment that demonstrates the purpose of quotes:

1. Enter the following command to create a filename with a space in it and then open it with Vim:

       sudo touch "foo bar.txt"
       vim "foo bar.txt"

2. In Vim, insert some text with the following key sequence: `i` `hello` `<esc>`.

3. Now enter the following command in Vim to save the file:

       :w !sudo tee %

4. In another instance of the terminal, enter the following command to check the content of the file:

       cat "foo bar.txt"

   The file still appears empty. Nothing was saved to this file.

5. Now enter the following commands:

       cat foo
       cat bar.txt

   Both files contain the text `hello` in them.

This experiment shows that due to the lack of quotes around `%`, the command `tee %` expands to `tee foo bar.txt` which ends up writing the content of the buffer to both files `foo` and `bar.txt` but not to `"foo bar.txt"` as we desire.

This is why we need to write `tee "%"` so that it expands to `tee "foo bar.txt"` and the content of the buffer is written to the file named `"foo bar.txt"`.

Very useful, thanks for sharing.

I have often wished there were something equivalent for nano. Of course you can just save to another file and `sudo mv` it into place.

In the spirit of this trick, you could set the `SPELL` environment variable to a script that does

    #!/bin/sh
    read -p "Path: " FILENAME
    cat "$1" | sudo tee "$FILENAME"

and then invoke it with `^T` from nano. Bonus points: Extract the destination filename automatically from `ps -p $PPID -o command=` (somewhat portable) or from `/proc` (Linux).

RGovostes, Thanks for the interesting idea to make this trick work with nano. Based on your comment, I wrote this script to automatically detect the destination filename when invoked with `^T` from nano.

    #!/bin/sh
    set -e
    COMMAND=$(ps -p $PPID -o args=)
    FILENAME=${COMMAND#*nano }
    printf "Write to $FILENAME? (y/n) "
    read ANSWER
    [ "$ANSWER" = y ] && sudo tee "$FILENAME" < "$1" > /dev/null

After saving this file to, say, `/usr/local/bin/sudowrite`, it can be set up for usage like this:

    sudo chmod u+x /usr/local/bin/sudowrite
    export SPELL=/usr/local/bin/sudowrite

Here is how to test it:

    sudo touch foo.txt
    nano foo.txt

Now write some text and try to save it by typing `ctrl` + `o` followed by `enter`. The following error should appear:

    [ Error writing foo.txt: Permission denied ]

Now type `ctrl` + `t` followed by `y` and `enter` to save the file successfully using the script we wrote above.

I just use vim-eunuch which includes a `:SudoWrite` in its list of goodies.

Everything in the plugin is pretty easy to live without but in my mind the simple plugin to have everything on-hand is worth it.

I have got this in my ~/.vimrc now:

    command W w !sudo tee "%" > /dev/null

This is a nice tip! I ended up adding this to my ~/.vimrc:

    command W execute 'silent write !sudo tee "%" > /dev/null' | edit!

Thanks for the tip! Adding this to my Vim configuration:

    com W exe 'sil w !sudo tee "%" > /dev/null' | e!