Comments on Vim Sudo Write Trick

Post Comment

Mr. Long Long said:

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

08 May 2021 15:27 GMT (#1 of 11 comments)

CRMD said:

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

30 Oct 2021 16:58 GMT (#2 of 11 comments)

LP said:

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

30 Oct 2021 20:06 GMT (#3 of 11 comments)

Susam Pal said:

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".

30 Oct 2021 23:00 GMT (#4 of 11 comments)

Oars said:

Very useful, thanks for sharing.

30 Oct 2021 23:41 GMT (#5 of 11 comments)

RGovostes said:

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).

31 Oct 2021 01:56 GMT (#6 of 11 comments)

Susam Pal said:

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.

31 Oct 2021 05:31 GMT (#7 of 11 comments)

Kevin Cox said:

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.

11 Dec 2021 11:41 GMT (#8 of 11 comments)

Jen said:

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

command W w !sudo tee "%" > /dev/null
11 Dec 2021 15:19 GMT (#9 of 11 comments)

Mario said:

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

command W execute 'silent write !sudo tee "%" > /dev/null' | edit!
11 Dec 2021 18:35 GMT (#10 of 11 comments)

Toby said:

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

com W exe 'sil w !sudo tee "%" > /dev/null' | e!
12 Dec 2021 21:18 GMT (#11 of 11 comments)
Post Comment