为了账号安全,请及时绑定邮箱和手机立即绑定

vim“使用sudo编写”技巧如何工作?

vim“使用sudo编写”技巧如何工作?

心有法竹 2019-11-21 10:16:40
你们中许多人可能已经看到了允许您在需要root权限的文件上写命令的命令,即使您忘记使用sudo打开vim时也是如此::w !sudo tee %问题是我不明白这里到底发生了什么。我已经想通了: w为此                                                        *: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 |:!|.因此它将所有行作为标准输入传递。该!sudo tee零件tee具有管理员权限。为了使所有人都理解,%应该输出文件名(作为的参数tee),但是我找不到关于此行为的帮助参考。tl; dr有人可以帮我剖析此命令吗?VIM 须藤
查看完整描述

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部分显式丢弃了标准输出,因为正如我所说,因为我们不需要将任何内容传递给另一个管道命令。


查看完整回答
反对 回复 2019-11-21
?
烙印99

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。


查看完整回答
反对 回复 2019-11-21
  • 3 回答
  • 0 关注
  • 859 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信