3 回答
TA贡献1712条经验 获得超3个赞
在:w !sudo tee %...
% 表示“当前文件”
正如eugene y所指出的,%确实的意思是“当前文件名”,将其传递给tee它,以便它知道要覆盖哪个文件。
(在替换命令,这是略有不同;如:help :%所示,它是equal to 1,$ (the entire file)(感谢@Orafu的指出,这并不评估为文件名)。例如,。:%s/foo/bar意思是“ 在当前文件,替换的出现foo与bar”如果你亮点键入一些文本之前:s,您会看到突出显示的行取代了%您的替换范围。)
:w 没有更新您的文件
此技巧的一个令人困惑的部分是,您可能会认为:w正在修改文件,但事实并非如此。如果您打开并修改了file1.txt,然后运行:w file2.txt,那将是“另存为”;file1.txt不会被修改,但是当前缓冲区的内容将发送到file2.txt。
相反file2.txt,您可以替代shell命令来接收缓冲区内容。例如,:w !cat将仅显示内容。
如果Vim不是使用sudo访问运行的,则它:w不能修改受保护的文件,但是如果将缓冲区内容传递给shell,则可以使用sudo运行shell 中的命令。在这种情况下,我们使用tee。
理解三通
至于tee,tee在正常的bash管道情况下,将命令描述为T形管道:它将输出定向到指定的文件,并将其发送到标准输出,该命令可以由下一个管道命令捕获。
例如,在中ps -ax | tee processes.txt | grep 'foo',进程列表将被写入文本文件并传递给grep。
+-----------+ tee +------------+
| | -------- | |
| ps -ax | -------- | grep 'foo' |
| | || | |
+-----------+ || +------------+
||
+---------------+
| |
| processes.txt |
| |
+---------------+
(使用Asciiflow创建的图。)
有关更多信息,请参见tee手册页。
发球台
在您的问题描述的情况下,使用teehack是因为我们忽略了它所做的一半。sudo tee写入文件,还将缓冲区内容发送到标准输出,但是我们忽略标准输出。在这种情况下,我们不需要将任何内容传递给另一个管道命令。我们只是将其tee用作写入文件的另一种方式,因此可以使用来调用它sudo。
使这个技巧变得容易
您可以将其添加到您的工具中.vimrc以使其易于使用:只需键入:w!!。
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %
该> /dev/null部分显式丢弃了标准输出,因为正如我所说,因为我们不需要将任何内容传递给另一个管道命令。
TA贡献1829条经验 获得超13个赞
在执行的命令行中,%代表当前文件名。记录在: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.
如您所知:w !cmd,将当前缓冲区的内容传递给另一个命令。是什么tee做的是标准输入复制到一个或多个文件,也到标准输出。因此,在成为root的同时:w !sudo tee % > /dev/null有效地将当前缓冲区的内容写入当前文件。可以用于此目的的另一个命令是:dd
:w !sudo dd of=% > /dev/null
作为快捷方式,您可以将此映射添加到您的.vimrc:
" Force saving files that require root permission
cnoremap w!! w !sudo tee > /dev/null %
通过上面的命令,您可以键入:w!!<Enter>将文件另存为root。
- 3 回答
- 0 关注
- 859 浏览
添加回答
举报