vim 保存只读文件的修改

  有些时候用vim打开一些系统文件需要进行修改,改完之后发现没有进行sudo操作或者没有切到root权限下,通过网络搜索发现,其实在vim中是可以获取sudo权限并进行保存文件操作的。
  1. :w ! sudo tee %  
      命令:w ! {cmd}, 让vim执行一个外部命令{cmd},然后把当前缓冲区的内容从stdin传入。

      tee是一个把stdin保存到文件的小工具。

      %是vim当中一个只读寄存器的名字,保存着当前编辑文件的文件路径。%: 在执行外部命令时,%会扩展成当前文件名;这个%区别于替换时的%,替换时%的意义是代表整个文件,而不是文件名

      所以执行这个命令,首先w!将当前改动保存到了stdin然后切换到sudo权限,使用tee将stdin中的内容保存到当前文件。



% 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', 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.

猜你喜欢

转载自blog.csdn.net/abccheng/article/details/77948657