Unix:混乱使用Tee -command

时间:2009-04-18 23:23:29

标签: unix tee

手动说明发球台是“管道配件” - 工具。案例[1]使我感到困惑:

1。情况下

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

2。情况下

:w !sudo tee %

从案件中很难理解发球台的逻辑。发球怎么样?

8 个答案:

答案 0 :(得分:36)

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

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

“foo bar”将回显到附加到/path/to/some/file的标准输出。可以把发球台想象成一个管道中的“T”接头,将输出分成另外两个管道。

答案 1 :(得分:12)

teestdin复制到stdout(如cat)并另外将所有内容写入指定文件。以sudo这种方式使用它可以将信息推送到特权模式,同时监控正确的东西是否存在。

另请注意,由于在shell中处理重定向的方式几乎相当于

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

将无效,因为重定向将由调用用户完成,而不是由sudo目标用户完成。

答案 2 :(得分:11)

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

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

例如

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

  • -i忽略中断。

enter image description here

使用sudo并在问题中将示例附加到文件

ls -l | sudo tee -a file.txt 

答案 3 :(得分:4)

案例解释

<强> 1。使用sudo-和-tee命令升级权限

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

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/这样的地方很有用,你会在那里找到只读文件。

使用tee-command的逻辑

它就像是Git中的一个分支,或者更好,请参阅the T analogy by Rick Copeland。希望修改后的示例(original)有助于理解其用法:

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

答案 4 :(得分:2)

请记住,tee的目标不仅限于常规文件,还可以是设备,FIFO等。此外,您可以管道到另一个tee调用,依此类推。 : - )

答案 5 :(得分:1)

我发现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命令输入另一个命令。

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

答案 6 :(得分:0)

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

如果您显示tee被称为超级用户(通过sudo),它的唯一目的是将文件编写为超级用户,而不是用户执行回声。

答案 7 :(得分:0)

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