tee命令核心是数据分流:将管道输入同时输出到终端和文件,并可继续传递给后续命令;支持追加(-a)、多文件、错误合并(2>&1)等关键用法。

tee 和管道组合,核心是让一条数据流“一分二用”:既实时可见,又持久留存,还能继续加工。关键不在命令本身多难,而在流向是否理清、错误是否捕获、覆盖还是追加是否明确。
管道本质:只传 stdout,不碰 stderr
管道 | 只接管前一个命令的标准输出(stdout,文件描述符 1),标准错误(stderr,文件描述符 2)默认仍输出到终端,不会自动进管道。这意味着:
- 如果命令报错,grep、awk 等后续命令完全看不到这些错误行
- 想让错误也参与过滤或记录,必须显式重定向:2>&1 把 stderr 合并到 stdout,再进管道
- 错误合并要写在管道前,顺序不能颠倒,例如:
find /tmp -name "*.log" 2>&1 | grep "Permission"
tee 的定位:T 型分流器,不是简单保存
tee 不是“把输出存个文件就完事”的工具,它是管道中的分流节点——输入进来,一份原样吐给下一级命令(或终端),另一份抄送至指定文件(可多个)。典型用法:
-
边看边存日志:
make build 2>&1 | tee build.log—— 实时显示编译过程,同时完整记入文件 -
存多份且不干扰后续处理:
ps aux | grep nginx | tee /tmp/nginx-pids.txt | awk '{print $2}'—— 进程 ID 既存文件,又提取出来供 awk 处理 -
追加而非覆盖:加 -a 参数,避免每次运行都清空历史,如
date | tee -a run_history.log
与重定向混用时的常见陷阱
重定向(>、>>、2>)和管道 | 共存时,Shell 按从左到右解析,且重定向优先级更高。错误写法会导致数据“消失”:
-
ls /root >out.txt | grep "conf"❌ —— ls 输出被直接写入 out.txt,管道收不到任何内容,grep 空转 -
ls /root 2>&1 | grep "conf"✅ —— 错误和正常输出都进管道,grep 能匹配到权限拒绝等提示 - 想同时保存全部输出+实时筛选关键行:
docker logs app 2>&1 | tee app.log | grep -E "(ERROR|panic)"
进阶技巧:分组 + 统一重定向 + tee 协同
单条命令受限,而用 ( ) 分组后,可对整段流程统一控制流向:
- 将一组命令的完整输出(含所有错误)存为日志:
(curl -I https://api.example.com; echo "---"; date) &> full_trace.log - 想既看到终端输出、又存日志、还提取某字段:
(df -h; free -m) 2>&1 | tee sysstat.log | awk '/^\/dev\/sd/ {print $5}' - 分离 stdout 与 stderr 到不同文件,且保持原始时序(避免竞态):
(cmd 2>err.log) >out.log











