In :w !sudo tee %
...
(在:w !sudo tee %
...)
%
means "the current file" (%
表示“当前文件”)
As eugene y pointed out , %
does indeed mean "the current file name".
(正如eugene指出的 , %
确实意味着“当前文件名”。)
Another use for this in Vim is in substitution commands. (Vim中的另一个用途是替换命令。)
For example, :%s/foo/bar
means " in the current file , replace occurrences of foo
with bar
." (例如, :%s/foo/bar
表示“ 在当前文件中 ,用bar
替换foo
出现次数”。)
If you highlight some text before typing :s
, you'll see that the highlighted lines take the place of %
as your substitution range. (如果在键入:s
之前突出显示某些文本,您会看到突出显示的行代替%
作为替换范围。)
:w
isn't updating your file (:w
没有更新您的文件)
One confusing part of this trick is that you might think :w
is modifying your file, but it isn't.
(这个技巧的一个令人困惑的部分是你可能会想:w
正在修改你的文件,但事实并非如此。)
If you opened and modified file1.txt
, then ran :w file2.txt
, it would be a "save as"; (如果您打开并修改了file1.txt
,则运行:w file2.txt
,它将是“另存为”;)
file1.txt
wouldn't be modified, but the current buffer contents would be sent to file2.txt
. (file1.txt
不会被修改,但当前缓冲区内容将被发送到file2.txt
。)
Instead of file2.txt
, you can substitute a shell command to receive the buffer contents .
(您可以替换shell命令来接收缓冲区内容 ,而不是file2.txt
。)
For instance, :w !cat
will just display the contents. (例如, :w !cat
将只显示内容。)
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 .
(如果Vim没有运行sudo访问,它的:w
不能修改受保护的文件,但是如果它将缓冲区内容传递给shell,shell中的命令可以用sudo运行 。)
In this case, we use tee
. (在这种情况下,我们使用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.
(至于tee
,在正常的bash管道情况下将tee
命令描绘成T形管道:它将输出定向到指定的文件, 并将其发送到标准输出 ,可以通过下一个管道命令捕获。)
For example, in ps -ax | tee processes.txt | grep 'foo'
(例如,在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
.
(ps -ax | tee processes.txt | grep 'foo'
,进程列表将被写入文本文件并传递给grep
。)
+-----------+ tee +------------+
| | -------- | |
| ps -ax | -------- | grep 'foo' |
| | || | |
+-----------+ || +------------+
||
+---------------+
| |
| processes.txt |
| |
+---------------+
(Diagram created with Asciiflow .)
((使用Asciiflow创建的图表 。))
See the tee
man page for more info.
(有关详细信息,请参阅tee
手册页 。)
Tee as a hack (发球作为一个黑客)
In the situation your question describes, using tee
is a hack because we're ignoring half of what it does .
(在你的问题所描述的情况下, 使用tee
是一种黑客攻击,因为我们忽略了它的一半 。)
sudo tee
writes to our file and also sends the buffer contents to standard output, but we ignore standard output . (sudo tee
写入我们的文件并将缓冲区内容发送到标准输出,但我们忽略标准输出 。)
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
. (我们只是使用tee
作为编写文件的替代方式,以便我们可以使用sudo
调用它。)
Making this trick easy (让这个技巧变得容易)
You can add this to your .vimrc
to make this trick easy-to-use: just type :w!!
(你可以将它添加到.vimrc
以使这个技巧易于使用:只需输入: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.
(> /dev/null
部分显式抛弃标准输出,因为正如我所说,我们不需要将任何内容传递给另一个管道命令。)