linux中的文本分接流tee命令介绍

下面以 Ubuntu(实际上是通用 GNU/Linux)环境为背景,系统地讲解 tee 命令的用法和原理。内容会从基础到进阶,包含常见例子和一些实用技巧。


一、tee 是什么?

tee 是一个标准的 Unix/Linux 命令,用来:

从标准输入读取数据,同时把数据输出到标准输出(通常是终端)和一个或多个文件中。

很像英文里的 "T 字接头":

  • 一端接收输入(管道中上一个命令的输出),
  • 一端继续往下传(标准输出),
  • 另一端分流到文件中保存。

典型语法

bash 复制代码
tee [OPTION]... [FILE]...

常用选项:

  • -a, --append:以追加方式写入文件(不覆盖原内容)
  • -i, --ignore-interrupts:忽略中断信号(Ctrl+C 等)
  • --help:显示帮助信息
  • --version:显示版本信息(来自 coreutils)

二、最基本用法:边看边保存输出

示例 1:保存命令输出到文件,同时在终端显示

bash 复制代码
ls -l | tee output.txt

效果:

  • 你在终端照样能看到 ls -l 的输出;
  • 同时输出内容被写入到 output.txt
  • 默认是覆盖写入(每次都会重写该文件)。

如果你用的是重定向:

bash 复制代码
ls -l > output.txt

则输出只会写入文件,不会在屏幕上显示

tee 是"保留屏幕显示 + 另存为文件"。


三、追加写入而不是覆盖:-a

tee 默认会覆盖文件内容,如果你希望将输出追加到文件末尾,使用 -a

bash 复制代码
ls -l | tee -a output.txt

多次执行后,output.txt 会不断增加内容,而不会被清空。

典型场景:

  • 一天中多次运行同一脚本,想把每次的日志都追加进同一个日志文件;
  • 分步骤执行命令,把每一步的输出续写到一个汇总文件中。

四、写入多个文件

tee 可以同时写入多个文件(包括追加的情况):

bash 复制代码
echo "hello" | tee file1.txt file2.txt

输出:

  • 终端显示 hello
  • file1.txt 内容为 hello
  • file2.txt 内容为 hello

结合 -a

bash 复制代码
echo "another line" | tee -a file1.txt file2.txt

两个文件都会追加这行内容。


五、实际应用场景

1. 保存命令执行过程(日志记录)

示例:保存安装日志
bash 复制代码
sudo apt update | tee apt-update.log
sudo apt upgrade | tee -a apt-update.log
  • 第一个命令:新建日志文件并写入 apt update 的输出;
  • 第二个命令:把 apt upgrade 的输出追加到同一个日志中。

2. 一边查看日志,一边保存日志

bash 复制代码
dmesg | tee dmesg.log
  • 你能看到 dmesg 输出;
  • 同时保存到 dmesg.log

比起:

bash 复制代码
dmesg > dmesg.log

的优点是:操作过程可视化,不用等命令结束后再看文件。

3. 与 sudo 配合:在需要 root 权限写文件时

这是 tee 非常常用、也非常"关键"的用途。

问题:重定向符号 > 不受 sudo 保护
bash 复制代码
sudo echo "something" > /etc/someconfig.conf

看起来像是"用 root 权限写文件",

但实际上:

  • sudo 只作用在 echo
  • 重定向 > 是由 当前 shell 执行的,仍然用的是普通用户权限
  • 这通常会报错:Permission denied
正确做法:用 tee 提升写入权限
bash 复制代码
echo "something" | sudo tee /etc/someconfig.conf
  • echo 以普通用户运行即可;
  • teesudo 权限下运行,可以写受限文件;
  • 内容仍会显示在终端。

如果不想让内容在终端重复出现(特别是配置内容很多时),可以重定向 tee 的标准输出到 /dev/null

bash 复制代码
echo "something" | sudo tee /etc/someconfig.conf > /dev/null

bash 复制代码
echo "something" | sudo tee -a /etc/someconfig.conf >/dev/null

再强调一遍:需要 root 权限写文件 + 又想用管道 时,几乎都用这类模式。

4. 长时间命令的"实时备份输出"

例如你在运行一个耗时很久的编译命令:

bash 复制代码
make 2>&1 | tee build.log

这里 2>&1 是把标准错误(2)重定向到标准输出(1),然后一起交给 tee

好处:

  • 终端实时看到所有编译信息(包括错误信息);
  • 日志完整 保存到 build.log,方便之后搜索。
  • 如果终端断开、滚动太多看不全------没关系,日志都在文件里。

六、tee 与重定向/管道的配合

1. 同时保存和继续做后续处理

tee 输出到标准输出的内容,还可以继续通过管道传给后续命令。

bash 复制代码
ls -l | tee ls.log | grep "txt"

流程:

  1. ls -l 的结果进入 tee
  2. tee 把结果 写入文件 ls.log
  3. 同时把同样的数据传给下一个命令 grep "txt"
  4. 最终你只在终端看到 grep 过滤后的内容,但 ls.log 中保存的是完整列表

这是 tee 一个很典型的作用:
中途拦截数据,做一份"备份",但又不打断原有管道的流程。


七、常见选项:-i 忽略中断

bash 复制代码
some-command | tee -i output.log

-i (--ignore-interrupts):让 tee 忽略中断信号(SIGINT),一般是避免因为你按了 Ctrl+C 导致 tee 中途退出。

实际使用中这个选项不算特别常用,但在某些长时间运行的管道场景下会涉及。


八、与文本处理工具联合使用的例子

1. 同时统计 + 保存完整数据

假设你有一个很长的日志流:

bash 复制代码
journalctl -f | tee full.log | grep "error"
  • full.log:保存全部日志;
  • 终端上只显示含有 "error" 的行;
  • 日志写入是实时的。

2. 格式化后保存

bash 复制代码
ps aux | tee ps_raw.log | awk '{print $1, $2, $11}' | tee ps_short.log

这里用了两次 tee

  • 第一次保存"原始的进程信息"到 ps_raw.log
  • 然后用 awk 抽取字段;
  • 再保存"简化版的进程列表"到 ps_short.log

九、tee 与权限、shell 的一些细节

  1. tee 写文件的权限 取决于运行 tee 的用户,而不是管道前面那个命令。
  2. >>>shell 的内建语法 ,和 tee普通程序有本质区别。
  3. sudo,要注意要放在 tee 前面
    • echo xxx | sudo tee file
    • sudo echo xxx | tee file(重定向还是普通权限)

十、与 /dev/tee 无关

有些人会把 tee 和某些设备节点混淆,实际:

  • tee 是一个用户空间程序(通常在 /usr/bin/tee
  • 它不是一个设备文件(和 /dev/null/dev/zero 不同)

十一、简单对比:tee vs 重定向

功能需求 推荐用法
只写文件,不显示在终端 cmd > file
只追加文件,不显示终端 cmd >> file
显示在终端 + 覆盖写文件 `cmd
显示在终端 + 追加写文件 `cmd
root 权限写文件(管道中) `cmd
中途"分流"输出给后续命令 `cmd

十二、在 Ubuntu 中查看 tee 的帮助

你可以在终端里直接查看完整文档:

bash 复制代码
man tee

或简单帮助:

bash 复制代码
tee --help

相关推荐
xlq223224 分钟前
40.线程控制
linux
l1t35 分钟前
DeepSeek总结的PostgreSQL使用 RDTSC 降低 EXPLAIN ANALYZE 的计时开销
数据库·postgresql
lagrahhn35 分钟前
Oracle中各个c版本介绍
数据库·oracle
day day day ...1 小时前
MyBatis条件误写引发的查询条件污染分析与防范
java·服务器·tomcat
知识分享小能手1 小时前
MongoDB入门学习教程,从入门到精通,在生产环境中设置MongoDB(21)
数据库·学习·mongodb
TechMasterPlus1 小时前
Linux U-Boot 与内核启动流程深度解析:从上电到 Shell 的完整之旅
linux·运维·服务器
XDHCOM1 小时前
ORA-12445报错:无法更改列隐藏属性,Oracle故障修复与远程处理,网友推荐解决方案
数据库·oracle
大白菜和MySQL1 小时前
Linux下dhcp服务搭建
linux·运维·服务器
大白菜和MySQL1 小时前
linux系统环境常用命令
android·linux·adb
麒麟ZHAO1 小时前
鸿蒙flutter第三方库适配 - 文件对比工具
数据库·redis·flutter·华为·harmonyos