Unix:混淆使用Tee命令

手册指出,三通是一个“pipe件”工具。 案件[1]使我困惑:

案例

echo "foo bar" | sudo tee -a /path/to/some/file 

2.情况

 :w !sudo tee % 

从案件中很难理解发球的逻辑。 发球台如何工作?

通常使用tee来分割程序的输出,使其可以被显示并保存在一个文件中。 在另一个命令或程序更改数据之前,该命令可用于捕获中间输出。 tee命令读取标准输入,然后将其内容写入标准输出。 它同时将结果复制到指定的文件或变量中

 tee [OPTION]... [FILE]... 

例如

 tee [ -a ] [ -i ]... [ File ]... 
  • -a将输出追加到文件的末尾而不是写入。

  • -i忽略中断。

在这里输入图像说明

随着sudo和追加到你的例子在文件中的问题

 ls -l | sudo tee -a file.txt 

tee用于拆分命令流水线,允许您将命令的输出保存到文件沿着流水线发送。 在第一个例子中,你给了::

 echo "foo bar" | sudo tee -a /path/to/some/file 

“foo bar”将被回显到标准输出并附加到/path/to/some/file 。 想象T形管道中的“T”接头,将输出分成两个其他管道。

tee复制stdin stdoutstdout (像cat ),另外写入所有命名的文件。 通过sudo这种方式使用它,可以将信息推送到特权模式,同时监视是否有正确的信息。

还要注意,由于在shell中处理重定向的方式几乎是等价的

 sudo echo "foo bar" > /path/to/some/file 

将不起作用,因为重定向将由主叫用户完成,而不是由sudo目标用户完成。

案件解释

1.使用sudo-和-tee命令升级权限

这个例子不是关于逻辑,而是约定。 它显示了提升权限的约定:

 echo "Body of file..." | sudo tee root_owned_file > /dev/null 

这个例子显示了tee被用来绕过sudo命令中固有的限制。 sudo无法将标准输出传送到文件。 通过将它的stdout流转储到/ dev / null中,我们也抑制了控制台中的镜像输出。

2.用Vim运行sudo-commands

既然你可以在Vim中使用Sudo命令,如果你忘记以sudo的身份运行,你可以使用这个命令。 这在诸如/etc/init.d/的地方很有用,在这里你会找到只读文件。

逻辑与发球命令

它就像Git中的一个分支,或者更好,请看Rick Copeland的T类比 。 希望修改的例子(原文)有助于理解它的使用:

 curl "http://en.wikipedia.org/wiki/Pipeline_(Unix)" | tee original_site | sed 's/[^a-zA-Z ]/ /g' | tr 'AZ ' 'az\n' | grep '[az]' | sort -u | comm -23 - /usr/share/dict/words 

请记住, tee的目标不限于常规文件,而可以是设备,FIFO等。另外,您可以管道到另一个tee调用,等等。 🙂

我发现tee命令在调试包含长管道的shell脚本时非常有用。 这是一个可怕的shell脚本的末尾,这个脚本在Perl中被重写了十多年,但仍然有效。 (这是1998年的最后一次修改,正好如此。)

 # If $DEBUG is yes, record the intermediate results. if [ "$DEBUG" = yes ] then cp $tmp.1 tmp.1 cp $tmp.2 tmp.2 cp $tmp.3 tmp.3 tee4="| tee tmp.4" tee5="| tee tmp.5" tee6="| tee tmp.6" tee7="| tee tmp.7" fi # The evals are there in case $DEBUG was yes. # The hieroglyphs on the shell line pass on any control arguments # (like -x) to the sub-shell if they are set for the parent shell. for file in $* do eval sed -f $tmp.1 $file $tee4 | eval sed -f $tmp.3 $tee5 | eval sh ${-+"-$-"} $tee6 | eval sed -f $tmp.2 $tee7 | sed -e '1s/^[ ]*$/--@/' -e '/^--@/d' done 

运行的三个sed脚本很可怕 – 我不打算给他们看。 这也是eval一个半体面的使用。 正常的临时文件名($ tmp.1等)由固定名称(tmp.1等)保存,中间结果保存在tmp.4 .. tmp.7中。 如果我正在更新命令,它将使用"$@#"而不是“ $* ”,如图所示。 而且,当我调试它时,参数列表中只有一个文件,所以调试文件的践踏对我来说不是问题。

请注意,如果您需要这样做,您可以一次创建多个输入副本; 不需要将一个tee命令送入另一个命令。

如果有人需要它,我有一个叫做tpipe的变种, tpipe输出的副本发送到多个管道而不是多个文件。 即使其中一个管道(或标准输出)提前终止,它也会继续运行。 (查看我的个人资料获取联系信息。)

tee只是将输出镜像到一个文件中,该文件可以被指定为tee的参数。

在这种情况下,你显示tee被称为超级用户(通过sudo),它的唯一目的是写一个文件作为超级用户,而不是如果用户做回声。

tee命令简单地创建N + 1个文件,1个副本传递给stdout和其他人提供给tee(即文件)的参数,其中N:传递给tee的agruments的数量