Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In <code>:w !sudo tee %</code>...</p> <h2><code>%</code> means "the current file"</h2> <p>As <a href="https://stackoverflow.com/a/2600852/211563">eugene y pointed out</a>, <code>%</code> does indeed mean "the current file name". Another use for this in Vim is in substitution commands. For example, <code>:%s/foo/bar</code> means "<strong>in the current file</strong>, replace occurrences of <code>foo</code> with <code>bar</code>." If you highlight some text before typing <code>:s</code>, you'll see that the highlighted lines take the place of <code>%</code> as your substitution range.</p> <h2><code>:w</code> isn't updating your file</h2> <p>One confusing part of this trick is that you might think <code>:w</code> is modifying your file, but it isn't. If you opened and modified <code>file1.txt</code>, then ran <code>:w file2.txt</code>, it would be a "save as"; <code>file1.txt</code> wouldn't be modified, but the current buffer contents would be sent to <code>file2.txt</code>.</p> <p>Instead of <code>file2.txt</code>, you can <strong>substitute a shell command to receive the buffer contents</strong>. For instance, <code>:w !cat</code> will just display the contents.</p> <p>If Vim wasn't run with sudo access, its <code>:w</code> can't modify a protected file, but if it passes the buffer contents to the shell, <strong>a command in the shell <em>can</em> be run with sudo</strong>. In this case, we use <code>tee</code>.</p> <h2>Understanding tee</h2> <p>As for <code>tee</code>, picture the <code>tee</code> command as a T-shaped pipe in a normal bash piping situation: it directs output to specified file(s) and <strong>also sends it to standard output</strong>, which can be captured by the next piped command. </p> <p>For example, in <code>ps -ax | tee processes.txt | grep 'foo'</code>, the list of processes will be written to a text file <strong>and</strong> passed along to <code>grep</code>.</p> <pre><code> +-----------+ tee +------------+ | | -------- | | | ps -ax | -------- | grep 'foo' | | | || | | +-----------+ || +------------+ || +---------------+ | | | processes.txt | | | +---------------+ </code></pre> <p>(Diagram created with <a href="http://www.asciiflow.com/" rel="noreferrer">Asciiflow</a>.)</p> <p>See the <a href="http://ss64.com/bash/tee.html" rel="noreferrer"><code>tee</code> man page</a> for more info.</p> <h2>Tee as a hack</h2> <p>In the situation your question describes, <strong>using <code>tee</code> is a hack because we're ignoring half of what it does</strong>. <code>sudo tee</code> writes to our file and also sends the buffer contents to standard output, but <strong>we ignore standard output</strong>. We don't need to pass anything to another piped command in this case; we're just using <code>tee</code> as an alternate way of writing a file and so that we can call it with <code>sudo</code>.</p> <h2>Making this trick easy</h2> <p>You can add this to your <code>.vimrc</code> to make this trick easy-to-use: just type <code>:w!!</code>.</p> <pre><code>" Allow saving of files as sudo when I forgot to start vim using sudo. cmap w!! w !sudo tee &gt; /dev/null % </code></pre> <p>The <code>&gt; /dev/null</code> part <strong>explicitly</strong> throws away the standard output, since, as I said, we don't need to pass anything to another piped command.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload