Unix:混乱使用Tee -command

Unix: confusing use of the Tee -command

手册中指出,三通是一个"管道配件"工具。案例[1]让我困惑:

1。案例

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

2。案例

1
:w !sudo tee %

从案例中很难理解tee的逻辑。这个球座怎么用?


tee用于拆分命令管道,允许您将命令输出保存到文件中,并沿管道发送。在您给出的第一个示例中:

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

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


teestdin复制到stdout上(如cat一样),并将所有内容额外写入指定文件。用这种方式与sudo结合使用,可以将信息推送到一个特权模式,同时监控是否有合适的信息被发送到那里。

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

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

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


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

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

例如

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

  • -i忽略中断。

enter image description here

使用EDOCX1[4]并将问题中的示例附加到文件中

1
ls -l | sudo tee -a file.txt


案例说明

1。使用sudo和tee命令提升权限

这个例子不只是逻辑上的,而是惯例上的。它显示了升级权限的约定:

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

This example shows tee being used to
bypass an inherent limitation in the
sudo command. sudo is unable to pipe
the standard output to a file. By
dumping its stdout stream into
/dev/null, we also suppress the
mirrored output in the console.

2。使用vim运行sudo命令

由于可以将sudo命令与vim一起使用,因此如果忘记以sudo的形式运行,则可以使用该命令。它在/etc/in it.d/等您可以找到只读文件的地方很有用。

使用tee命令的逻辑

它就像吉特的一个分支,或者更好,请看里克·科普兰的T类比。希望修改后的示例(原始)有助于理解其用法:

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

记住,tee的目标不仅限于常规文件,还可以是设备、FIFO等。此外,您还可以通过管道连接到另一个tee调用,等等。-)


我发现tee命令在调试包含长管道的shell脚本时非常有用。这是一个可怕的shell脚本的结尾,该脚本在Perl中重写已经过期十年,但它仍然有效。(事实上,它最后一次修改是在1998年。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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命令馈送到另一个命令。

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


tee命令只创建n+1个文件,1个副本传递给stdout,其他副本传递给提供给tee的参数(ie文件)。式中n:传递到tee的参数数


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

在本例中,您显示tee被称为超级用户(通过sudo),它的唯一目的是,如果执行echo的用户以超级用户的身份编写文件。