能,但默认只捕获 stdout;stderr 需用 2>&1 重定向至管道才能被 tee 记录,且重定向必须紧贴命令左侧,否则失效;同时管道中命令退出码需用 ${pipestatus[0]} 获取。

能,但默认只捕获 stdout,stderr 会直接丢在终端上——必须手动重定向才能一并记录。
为什么 ls | tee output.txt 看起来没输出?
不是没输出,是终端渲染被干扰了:比如 ls 在管道中自动禁用颜色和列对齐,导致输出“看起来空”;或者缓冲区未刷出,尤其输入无换行时。
- 加
-p强制逐行刷新:ls | tee -p output.txt - 用
echo快速验证:echo "test" | tee output.txt—— 如果这也不显示,说明终端或 shell 有问题 - 避免 ANSI 控制序列污染日志:需要干净文本时,套一层
script -qec "your_cmd" /dev/null
怎么把 stderr 也一起记进文件?
tee 只读 stdin,而 shell 默认不把 stderr 接入管道。不重定向,错误就永远进不了文件。
- 正确写法:
make 2>&1 | tee build.log——2>&1必须紧贴命令,写在|前面 - 错误写法:
make | tee build.log 2>&1—— 这里2>&1重定向的是tee自己的 stderr,不是make的 - 要分开存 stdout/stderr?
tee不行,得用进程替换:make > >(tee stdout.log) 2> >(tee stderr.log >&2)
脚本里用 tee 为什么总返回 0?
管道最后一条命令的退出码会覆盖上游结果。some_cmd | tee log.txt 的 $? 是 tee 的,不是 some_cmd 的。
- 获取真实退出码:
some_cmd 2>&1 | tee log.txt; exit_code=$?不够,得用PIPESTATUS - 正确方式:
some_cmd 2>&1 | tee log.txt; exit_code=${PIPESTATUS[0]} - 追加写慎用
-a:高频小数据写入会触发大量系统调用,性能差;批量生成再写更稳
最常被忽略的是退出码覆盖和 stderr 重定向顺序——这两点一旦出错,日志看似完整,实际关键错误根本没被捕获。











