【问题标题】:Unix: confusing use of the 'tee' command [duplicate]Unix:混淆使用 Tee -command [重复]
【发布时间】:2010-10-20 08:26:09
【问题描述】:

手册指出三通是一种“管件”工具。 [1]的案例让我很困惑:

1.案例

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

2。案例

:w !sudo tee %

很难从案例中理解 tee 的逻辑。三通是如何工作的?

【问题讨论】:

标签: unix tee


【解决方案1】:

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

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

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

【讨论】:

  • 这就是名字的由来:-)
【解决方案2】:

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

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

例如

tee [ -a ] [ -i ]... [ File ]...
  • -a 将输出附加到 File 的末尾而不是覆盖它。

  • -i 忽略中断。

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

ls -l | sudo tee -a file.txt 

【讨论】:

  • 也许,当您已经使用 sudo 时,您可以展示如何将输出重定向到 less
【解决方案3】:

teestdin 复制到stdout(如cat)并将所有内容写入指定文件。以这种方式与sudo 一起使用它可以让人们将信息推送到特权模式,并同时监控是否有正确的东西到达那里。

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

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

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

【讨论】:

  • 如果标准输出数据太大怎么办?如何将数据推送到文件?按大小还是按时间段?
【解决方案4】:

案例说明

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

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

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

此示例显示 tee 用于 绕过内在的限制 须藤命令。 sudo 无法管道 标准输出到文件。经过 将其标准输出流转储到 /dev/null,我们也压制 控制台中的镜像输出。

2。用 Vim 运行 sudo 命令

由于您可以在 Vim 中使用 Sudo 命令,如果您忘记以 sudo 身份运行,您可以使用该命令。它在诸如 /etc/init.d/ 之类的地方很有用,您可以在其中找到只读文件。

使用 tee 命令的逻辑

它就像 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

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        如果您显示 tee 被称为超级用户(通过 sudo),其唯一目的是作为超级用户写入文件,而不是执行 echo 的用户。

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            猜你喜欢
            • 2016-04-24
            • 2010-10-12
            • 1970-01-01
            • 1970-01-01
            • 2012-12-16
            • 1970-01-01
            • 1970-01-01
            • 2014-12-06
            • 2018-03-21
            相关资源
            最近更新 更多