Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
344 views
in Technique[技术] by (71.8m points)

vim - vim“用sudo写”技巧如何工作?(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:

(很多人可能已经看到了允许你在需要root权限的文件上写的命令,即使你忘了用sudo打开vim:)

: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就是为了这个)

                                                        *: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.

(!sudo tee部分以管理员权限呼叫tee 。)

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.

(为了让所有人都有意义, %应输出文件名(作为tee的参数),但我找不到有关此行为的帮助的参考。)

tl;dr Could someone help me dissect this command?

(tl; dr有人可以帮我剖析这个命令吗?)

  ask by Doppelganger translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...