How does the vim "write with sudo" trick work?
Many of you have probably seen the command that allows you to write on a file that needs root permission, even when you forgot to open vim with sudo:
:w !sudo tee %
The thing is that I don't get what is exactly happening here.
 I have already figured this: w is for this  
                                                        *:w_c* *:write_c*
:[range]w[rite] [++opt] !{cmd}
                        Execute {cmd} with [range] lines as standard input
                        (note the space in front of the '!').  {cmd} is
                        executed like with ":!{cmd}", any '!' is replaced with
                        the previous command |:!|.
so it passes all the lines as standard input.
 The !sudo tee part calls tee with administrator privileges.  
 For all to make sense, the % should output the filename (as a parameter for tee ), but I can't find references on the help for this behavior.  
tl;dr Could someone help me dissect this command?
 % means "the current file"  
 As eugene y pointed out, % does indeed mean "the current file name".  Another use for this in Vim is in substitution commands.  For example, :%s/foo/bar means " in the current file , replace occurrences of foo with bar ."  If you highlight some text before typing :s , you'll see that the highlighted lines take the place of % as your substitution range.  
 :w isn't updating your file  
 One confusing part of this trick is that you might think :w is modifying your file, but it isn't.  If you opened and modified file1.txt , then ran :w file2.txt , it would be a "save as";  file1.txt wouldn't be modified, but the current buffer contents would be sent to file2.txt .  
 Instead of file2.txt , you can substitute a shell command to receive the buffer contents .  For instance, :w !cat will just display the contents.  
 If Vim wasn't run with sudo access, its :w can't modify a protected file, but if it passes the buffer contents to the shell, a command in the shell can be run with sudo .  In this case, we use tee .  
Understanding tee
 As for tee , picture the tee command as a T-shaped pipe in a normal bash piping situation: it directs output to specified file(s) and also sends it to standard output , which can be captured by the next piped command.  
 For example, in ps -ax | tee processes.txt | grep 'foo'  ps -ax | tee processes.txt | grep 'foo' ps -ax | tee processes.txt | grep 'foo' , the list of processes will be written to a text file and passed along to grep .  
     +-----------+    tee     +------------+
     |           |  --------  |            |
     | ps -ax    |  --------  | grep 'foo' |
     |           |     ||     |            |
     +-----------+     ||     +------------+
                       ||   
               +---------------+
               |               |
               | processes.txt |
               |               |
               +---------------+
(Diagram created with Asciiflow.)
 See the tee man page for more info.  
Tee as a hack
 In the situation your question describes, using tee is a hack because we're ignoring half of what it does .  sudo tee writes to our file and also sends the buffer contents to standard output, but we ignore standard output .  We don't need to pass anything to another piped command in this case;  we're just using tee as an alternate way of writing a file and so that we can call it with sudo .  
Making this trick easy
 You can add this to your .vimrc to make this trick easy-to-use: just type :w!!  .  
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %
 The > /dev/null part explicitly throws away the standard output, since, as I said, we don't need to pass anything to another piped command.  
 In the executed command line, % stands for the current file name .  This is documented in :help cmdline-special :  
In Ex commands, at places where a file name can be used, the following
characters have a special meaning.
        %       Is replaced with the current file name.
 As you've already found out, :w !cmd pipes the contents of the current buffer to another command.  What tee does is copy standard input to one or more files, and also to standard output.  Therefore, :w !sudo tee % > /dev/null effectively writes the contents of the current buffer to the current file while being root .  Another command that can be used for this is dd :  
:w !sudo dd of=% > /dev/null
 As a shortcut, you can add this mapping to your .vimrc :  
" Force saving files that require root permission 
cnoremap w!! w !sudo tee > /dev/null %
 With the above you can type :w!!<Enter> to save the file as root.  
 :w - Write a file.  
 !sudo - Call shell sudo command.  
 tee - The output of write (vim :w) command redirected using tee.  The % is nothing but current file name ie /etc/apache2/conf.d/mediawiki.conf.  In other words tee command is run as root and it takes standard input and write it to a file represented by %.  However, this will prompt to reload file again (hit L to load changes in vim itself):  
tutorial link
链接地址: http://www.djcxy.com/p/28612.html上一篇: 如何在vim中缩进特定的代码块?
下一篇: vim“用sudo编写”技巧如何工作?
