
别再只用重定向了Linux tee命令的5个实用场景从日志记录到管道调试在Linux系统管理中重定向操作符和几乎是每个用户最早掌握的技能之一。但当你开始处理更复杂的任务时会发现单纯的重定向存在明显局限——它要么将输出写入文件要么显示在终端无法同时兼顾。这就是tee命令大显身手的地方。想象一下这些场景调试一个复杂的管道命令时你想查看中间结果需要同时监控实时日志并保存到文件或者要以sudo权限写入文件却不想切换用户。这些正是tee命令的专长领域。作为管道中的三通接头它能将数据流同时导向终端和文件甚至多个目标。本文将深入五个实际工作场景展示tee如何成为系统管理员和开发者的效率利器。我们跳过基础语法直接聚焦于解决真实痛点的进阶用法。1. 实时监控与持久化日志记录处理长时间运行的进程时我们常面临两难选择用tail -f实时监控日志但重启后无法追溯用重定向保存日志却失去实时观察能力。tee完美解决了这个矛盾。典型应用服务启动日志的双重记录./start_server.sh 21 | tee -a server.log这个命令实现了21将标准错误合并到标准输出tee -a将输出同时显示在终端并追加到日志文件即使断开SSH连接重新登录后仍能查看完整日志高级技巧时间戳增强./long_running_task.sh 21 | while IFS read -r line; do echo $(date %Y-%m-%d %H:%M:%S) $line | tee -a timed.log done这个管道组合使用while read逐行处理输出为每行添加精确到秒的时间戳通过tee同时显示和记录带时间的信息注意在高速输出的场景中逐行处理可能影响性能。此时可考虑使用ts命令来自moreutils包替代自定义循环。2. 管道命令的中间调试复杂的管道命令一旦出现问题调试往往令人头疼。传统方法需要拆分管道逐步测试而tee允许我们在不中断流程的情况下检查中间结果。调试案例数据清洗管道假设我们有一个处理CSV文件的复杂管道cat data.csv | grep -v ^# | awk -F, $3 100 {print $1,$4} | sort | uniq result.txt当结果异常时可以插入tee检查各阶段输出cat data.csv | tee raw_data.txt | grep -v ^# | tee no_comments.txt | awk -F, $3 100 {print $1,$4} | tee filtered.txt | sort | uniq result.txt现在我们有三个中间文件raw_data.txt原始输入no_comments.txt过滤注释后的结果filtered.txt数值筛选后的数据对比调试法更专业的做法是创建对比调试脚本#!/bin/bash # 原始命令 original_cmd() { cat data.csv | grep -v ^# | awk -F, $3 100 {print $1,$4} | sort | uniq } # 调试命令 debug_cmd() { cat data.csv | tee /tmp/step1 | grep -v ^# | tee /tmp/step2 | awk -F, $3 100 {print $1,$4} | tee /tmp/step3 | sort | uniq } echo 原始输出 original_cmd echo 调试输出 debug_cmd echo 调试文件已保存到 /tmp/step[1-3]这种方法特别适合在自动化脚本中实现可复现的调试流程。3. 特权文件的安全写入需要写入系统保护文件时直接使用sudo重定向会失败因为重定向是由shell而非命令本身处理的sudo echo new config /etc/config.conf # 失败tee提供了优雅的解决方案echo new config | sudo tee /etc/config.conf /dev/null这里的关键点sudo应用于tee命令使其获得写入权限/dev/null抑制终端显示因为通常不需要看到配置内容保留tee的原子写入特性比临时文件方案更可靠生产环境最佳实践对于关键系统文件建议采用以下安全模式{ echo # 自动生成于 $(date) echo important_configvalue echo # 结束 } | sudo tee -a /etc/important.conf /dev/null这种模式使用代码块组织多行内容添加清晰的标记和时间戳使用-a追加而非覆盖原有配置完全避免临时文件可能导致的权限问题4. 自动化脚本的双输出保障在无人值守的自动化脚本中我们既需要实时查看运行状态又必须确保所有输出被完整记录。tee是实现这种双保险的理想工具。基础实现方案#!/bin/bash LOG_FILEscript_$(date %Y%m%d_%H%M%S).log exec (tee -a $LOG_FILE) 21 echo 脚本开始执行: $(date) # 后续所有命令的输出都会同时显示和记录 ...增强版日志管理系统更完善的方案应该包括日志轮转按级别过滤多目标输出#!/bin/bash set -euo pipefail LOG_DIR/var/log/my_script mkdir -p $LOG_DIR LOG_FILE$LOG_DIR/$(date %Y%m%d).log # 定义日志函数 log() { local level$1 shift echo [$(date %Y-%m-%d %H:%M:%S)] [$level] $* | \ tee -a $LOG_FILE | \ grep --colorauto -E ^|ERROR|WARN } # 使用示例 log INFO Starting processing log WARN This is a warning log ERROR Something went wrong这个实现特点按日期组织日志文件支持不同日志级别INFO/WARN/ERROR在终端高亮显示重要信息同时保留完整日志到文件5. 输出多路复用与进程协同tee最强大的能力之一是能够将单一输出分发到多个目的地这在复杂系统集成中尤为有用。多文件记录dmesg --follow | tee \ system.log \ (grep -i error errors.log) \ (grep -i usb usb_devices.log)这个命令实时监控内核消息同时写入三个文件system.log完整日志errors.log仅错误消息usb_devices.logUSB相关事件多进程协同处理更高级的用法是将输出分发给多个处理进程generate_report.sh | tee \ (send_to_email.sh) \ (upload_to_s3.sh) \ (analyze_stats.sh) \ final_report.pdf这种模式实现了原始报告生成一次并行执行多个后续处理邮件发送云存储备份数据分析同时保存最终PDF版本性能优化技巧当处理大量数据时匿名管道可能成为瓶颈。此时可以使用命名管道mkfifo my_pipe process1 my_pipe process2 my_pipe process3 my_pipe tee my_pipe final_output这种架构创建命名管道my_pipe让多个消费者并行处理数据保持生产者单一数据流