该手册指出,三通是一种“管件”工具。案例[1]让我感到困惑:
1.案例
echo "foo bar" | sudo tee -a /path/to/some/file
2.案例
:w !sudo tee %
很难从案例中理解 tee 的逻辑。三通是如何工作的?
tee
用于拆分命令管道,允许您将命令的输出保存到文件并沿管道发送。在您给出的第一个示例中:
echo "foo bar" | sudo tee -a /path/to/some/file
"foo bar" 将回显到标准输出并附加到/path/to/some/file
. 将三通想象成管道中的“T”形接头,将输出分成另外两个管道。
tee
复制stdin
到stdout
(like 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 无法将标准输出通过管道传输到文件。通过将其标准输出流转储到 /dev/null,我们还抑制了控制台中的镜像输出。
2. 用 Vim 运行 sudo-commands
由于您可以在 Vim 中使用 Sudo 命令,因此如果您忘记以 sudo 身份运行,您可以使用该命令。它在诸如 /etc/init.d/ 之类的地方很有用,您可以在其中找到只读文件。
使用 tee 命令的逻辑
它就像 Git 中的一个分支,或者更好,请参阅Rick Copeland 的 T 类比。希望修改后的示例(原始)有助于理解其用途:
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
请记住,目标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
命令输入另一个命令。
如果有人需要它,我有一个tee
被调用的变体,tpipe
它将输出的副本发送到多个管道而不是多个文件。即使其中一条管道(或标准输出)提前终止,它也会继续运行。(有关联系信息,请参阅我的个人资料。)
tee只是将输出镜像到一个文件中,该文件可以指定为tee的参数。
如果您显示tee被称为超级用户(通过sudo),其唯一目的是作为超级用户而不是执行回显的用户编写文件。
tee命令只是创建 N+1 个文件,一个副本传递给标准输出,其他副本传递给提供给tee的参数(即文件),其中 N 是传递给tee的参数数量。