Linux tee 指令详解:从基础到高级用法

Linux tee 指令详解:从基础到高级用法

tee 是 Linux 系统中一个强大的命令行工具,用于从标准输入(stdin)读取数据,并同时将数据写入标准输出(stdout)和一个或多个指定文件。它在管道(pipe)操作中尤为有用,允许用户在处理数据流时保存中间结果。tee 的名称来源于其功能类似于管道系统中的 T 形接头(tee),将数据流“分流”到多个目标。tee 广泛应用于日志记录、数据处理、脚本自动化和调试场景。


📚 什么是 tee 指令?

概述

tee 是一个 Linux 命令行工具,设计用于从标准输入读取数据,并将其同时输出到标准输出和一个或多个文件。它通常在管道操作中作为中间节点,允许用户在查看数据流的同时将其保存到文件中。tee 是 Linux/Unix 系统中的标准工具,预装于大多数发行版(如 Ubuntu、CentOS),是 shell 脚本和命令行工作流中的重要组成部分。

核心概念

  • 标准输入(stdin):tee 从管道或命令读取输入。
  • 标准输出(stdout):tee 将输入数据回显到终端。
  • 文件输出:tee 将输入数据写入指定文件。
  • 文件描述符:tee 主要操作 stdin(FD 0)和 stdout(FD 1),文件写入使用普通文件描述符。
  • 管道集成:tee 常用于管道链中,连接前后命令。

核心特点

  • 数据分流:同时输出到终端和文件。
  • 多文件支持:可写入多个目标文件。
  • 灵活性:支持覆盖或追加文件内容。
  • 兼容性:适用于 Bash、Zsh 等 shell 环境。
  • 自动化:在脚本中实现日志记录和数据捕获。

基本语法

tee [选项] [文件...]
常用选项
  • -a:追加到文件,而不是覆盖。
  • -i:忽略中断信号(如 Ctrl+C)。
  • –help:显示帮助信息。
  • –version:显示版本信息。
输入输出流程
  • 输入:从 stdin 读取(通常通过管道 |)。
  • 输出
    • 写入指定的文件(覆盖或追加)。
    • 回显到 stdout(终端或下一个管道命令)。

注意事项

  • 权限要求:写入文件需要相应权限,写入受限目录(如 /etc)需 sudo。
  • 覆盖风险:默认覆盖目标文件,需用 -a 追加。
  • 管道依赖:tee 通常与管道配合,无管道时需显式输入(如 echo)。
  • 中断处理:Ctrl+C 默认终止 tee,可用 -i 忽略。
  • 编码支持:确保终端和文件编码一致(如 UTF-8)。

🔧 tee 的常见用途

应用场景

  • 日志记录:实时查看命令输出并保存到日志文件。
  • 数据处理:在管道链中保存中间结果。
  • 调试分析:捕获命令输出以排查问题。
  • 脚本自动化:构建复杂工作流,记录关键数据。
  • 权限提升:结合 sudo 将输出写入受限文件。

🛠️ 基础用法与示例

准备工作

以下示例假设运行在 Bash shell(如 Ubuntu 22.04 或 CentOS 8,当前时间为 2025-05-31 19:37 CST)。我们将使用常见命令(如 ls、echo、ps)演示 tee 的功能。假设当前目录为 /home/user。

示例 1:将输出保存到文件并显示

命令
ls -l | tee dir_list.txt
cat dir_list.txt
解释
  • ls -l:列出当前目录的详细信息。
  • |:将 stdout 传递给 tee。
  • tee dir_list.txt:将输入同时写入 dir_list.txt 和终端。
  • cat dir_list.txt:验证文件内容。
输出示例
  • 终端:

    -rw-r--r-- 1 user user  123 May 31 19:00 file1.txt
    drwxr-xr-x 2 user user 4096 May 31 19:00 dir1
    -rw-r--r-- 1 user user  456 May 31 19:00 file2.txt
    
  • dir_list.txt(同终端输出):

    -rw-r--r-- 1 user user  123 May 31 19:00 file1.txt
    drwxr-xr-x 2 user user 4096 May 31 19:00 dir1
    -rw-r--r-- 1 user user  456 May 31 19:00 file2.txt
    
说明
  • 文件不存在时自动创建。
  • 默认覆盖 dir_list.txt。

示例 2:追加到文件

命令
echo "First entry" | tee -a log.txt
echo "Second entry" | tee -a log.txt
cat log.txt
解释
  • -a:追加到 log.txt,不覆盖。
  • 多次执行追加内容。
输出示例
  • 终端(每次 echo):

    First entry
    Second entry
    
  • log.txt:

    First entry
    Second entry
    

示例 3:写入多个文件

命令
ps aux | tee file1.txt file2.txt
cat file1.txt
cat file2.txt
解释
  • ps aux:列出所有进程。
  • tee file1.txt file2.txt:将输入写入两个文件并显示。
输出示例
  • 终端:

    user   12345  0.0  0.1 123456  7890 ?  Ss  19:00  0:00 /usr/bin/bash
    user   12346  0.0  0.2 456789 12345 ?  S   19:00  0:00 ps aux
    
  • file1.txt 和 file2.txt(内容相同):

    user   12345  0.0  0.1 123456  7890 ?  Ss  19:00  0:00 /usr/bin/bash
    user   12346  0.0  0.2 456789 12345 ?  S   19:00  0:00 ps aux
    

示例 4:结合管道继续处理

命令
ls -l | tee dir_list.txt | grep ".txt"
解释
  • tee dir_list.txt:保存 ls -l 输出到文件并传递到 stdout。
  • grep “.txt”:从 tee 的 stdout 过滤 .txt 文件。
输出示例
  • 终端:

    -rw-r--r-- 1 user user  123 May 31 19:00 file1.txt
    -rw-r--r-- 1 user user  456 May 31 19:00 file2.txt
    
  • dir_list.txt:

    -rw-r--r-- 1 user user  123 May 31 19:00 file1.txt
    drwxr-xr-x 2 user user 4096 May 31 19:00 dir1
    -rw-r--r-- 1 user user  456 May 31 19:00 file2.txt
    

示例 5:忽略中断信号

命令
echo "Processing..." | tee -i output.txt
# 按 Ctrl+C 中断
cat output.txt
解释
  • -i:忽略中断信号(SIGINT,Ctrl+C)。
  • 即使中断,tee 仍完成写入。
输出示例
  • 终端:

    Processing...
    ^C
    
  • output.txt:

    Processing...
    

示例 6:结合 sudo 写入受限文件

命令
ls -l | sudo tee /root/dir_list.txt
cat /root/dir_list.txt
解释
  • sudo tee:以 root 权限写入 /root 目录。
  • 管道允许非 root 用户的 ls 输出通过 tee 写入受限文件。
输出示例
  • 终端(需 root 权限查看):

    -rw-r--r-- 1 user user  123 May 31 19:00 file1.txt
    drwxr-xr-x 2 user user 4096 May 31 19:00 dir1
    -rw-r--r-- 1 user user  456 May 31 19:00 file2.txt
    
  • /root/dir_list.txt(同上)。


🚀 高级用法

概述

tee 的高级用法涉及复杂管道、文件描述符操作、脚本集成和错误处理,适合日志管理、数据处理和自动化场景。

🛡️ 1. 捕获 stderr 和 stdout

命令
ls /home/user /nonexistent 2>&1 | tee output.txt
cat output.txt
解释
  • 2>&1:将 stderr(FD 2)重定向到 stdout(FD 1)。
  • tee output.txt:捕获合并的 stdout 和 stderr。
输出示例
  • 终端和 output.txt:

    /home/user:
    file1.txt  dir1  file2.txt
    
    ls: cannot access '/nonexistent': No such file or directory
    
补充
  • 仅捕获 stderr:

    ls /home/user /nonexistent 2> >(tee error.txt)
    cat error.txt
    

    输出(error.txt):

    ls: cannot access '/nonexistent': No such file or directory
    

🔍 2. 多重管道与 tee

命令
ps aux | tee ps_output.txt | grep "bash" | tee bash_output.txt
cat ps_output.txt
cat bash_output.txt
解释
  • 第一个 tee:保存 ps aux 输出。
  • grep “bash”:过滤包含 “bash” 的行。
  • 第二个 tee:保存过滤结果。
输出示例
  • ps_output.txt:

    user   12345  0.0  0.1 123456  7890 ?  Ss  19:00  0:00 /usr/bin/bash
    user   12346  0.0  0.2 456789 12345 ?  S   19:00  0:00 ps aux
    
  • bash_output.txt:

    user   12345  0.0  0.1 123456  7890 ?  Ss  19:00  0:00 /usr/bin/bash
    

🔄 3. 动态日志记录

命令
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
top -b -n 1 | tee system_$TIMESTAMP.log
cat system_$TIMESTAMP.log
解释
  • top -b -n 1:批处理模式运行一次 top。
  • tee system_$TIMESTAMP.log:保存带时间戳的系统状态。
输出示例(system_20250531_193700.log)
top - 19:37:00 up 1:00,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 100 total,   1 running, 99 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 100.0 id,  0.0 wa,  0.0 hi,  0.0 si
...
用途
  • 定期记录系统状态。

⚡ 4. 结合 Here Document

命令
tee config.txt << EOF
[app]
host=localhost
port=8080
EOF
cat config.txt
解释
  • << EOF:Here Document 提供多行输入。
  • tee config.txt:将输入写入文件并显示。
输出示例
  • 终端和 config.txt:

    [app]
    host=localhost
    port=8080
    

🔐 5. 权限管理与 tee

命令
echo "test" | sudo tee -a /etc/test.conf
cat /etc/test.conf
解释
  • sudo tee -a:以 root 权限追加到受限文件。
  • 管道允许非 root 用户提供输入。
输出示例
  • 终端和 /etc/test.conf:

    test
    

⚠️ 使用 tee 时的注意事项

关键提示

  • 覆盖风险

    • 默认覆盖目标文件,需用 -a 追加。
  • 权限要求

    • 写入受限文件需 sudo tee:

      echo "data" | sudo tee /root/file.txt
      
  • 管道依赖

    • 无管道输入时,tee 等待 stdin(需 Ctrl+D 结束)。
  • 中断处理

    • Ctrl+C 默认终止,-i 可忽略。
  • 性能影响

    • 写入多个文件或大型数据可能增加 I/O 开销。
  • 编码问题

    • 确保终端和文件编码一致,避免乱码。

🌟 高级技巧与实战案例

概述

以下是高级技巧和实战案例,展示 tee 在复杂场景中的应用。

🖥️ 案例 1:实时日志监控

脚本
#!/bin/bash
LOG_FILE=/var/log/monitor.log

# 监控系统状态
while true; do
    top -b -n 1 | tee -a "$LOG_FILE"
    sleep 5
done
解释
  • top -b -n 1:每 5 秒捕获系统状态。
  • tee -a:追加到日志并显示。
  • 按 Ctrl+C 终止。
输出示例(monitor.log)
top - 19:37:00 up 1:00,  1 user,  load average: 0.00, 0.01, 0.05
...
top - 19:37:05 up 1:00,  1 user,  load average: 0.00, 0.01, 0.05
...
用途
  • 实时监控并记录系统性能。

📦 案例 2:数据处理流水线

脚本
#!/bin/bash
INPUT_FILE=data.txt
INTERMEDIATE=intermediate.txt
OUTPUT_FILE=processed.txt

# 创建输入文件
echo -e "apple\nbanana\napple\ncherry" > "$INPUT_FILE"

# 处理数据
cat "$INPUT_FILE" | tee "$INTERMEDIATE" | grep -v "banana" | sort | uniq | tee "$OUTPUT_FILE"

# 显示结果
echo "Intermediate:"
cat "$INTERMEDIATE"
echo "Final Output:"
cat "$OUTPUT_FILE"
解释
  • 保存中间结果(tee “$INTERMEDIATE”)。
  • 过滤、排序、去重后保存最终结果。
输出示例
  • intermediate.txt:

    apple
    banana
    apple
    cherry
    
  • processed.txt:

    apple
    cherry
    

🔒 案例 3:错误日志分离

脚本
#!/bin/bash
LOG_FILE=/tmp/output.log
ERROR_LOG=/tmp/error.log

# 运行命令
ls /home/user /nonexistent 2> >(tee "$ERROR_LOG" >&2) | tee "$LOG_FILE"

# 显示结果
echo "Standard Output:"
cat "$LOG_FILE"
echo "Error Output:"
cat "$ERROR_LOG"
解释
  • 2> >(…):将 stderr 送入 tee,保存并显示。
  • | tee:保存 stdout。
输出示例
  • LOG_FILE:

    /home/user:
    file1.txt  dir1  file2.txt
    
  • ERROR_LOG:

    ls: cannot access '/nonexistent': No such file or directory
    

📈 案例 4:动态配置文件生成

脚本
#!/bin/bash
CONFIG_FILE=/tmp/app.conf
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

# 生成配置文件
tee "$CONFIG_FILE" << EOF
# Generated at $TIMESTAMP
[app]
host=localhost
port=8080
debug=true
EOF

# 显示结果
cat "$CONFIG_FILE"
解释
  • 使用 Here Document 和 tee 创建配置文件。
  • 包含时间戳。
输出示例(app.conf)
# Generated at 2025-05-31 19:37:00
[app]
host=localhost
port=8080
debug=true

🔧 案例 5:自动化备份监控

脚本
#!/bin/bash
BACKUP_DIR=/tmp/backup
LOG_FILE=/tmp/backup.log
ERROR_LOG=/tmp/backup_error.log
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')

# 创建备份目录
mkdir -p "$BACKUP_DIR"

# 执行备份
tar -czf "$BACKUP_DIR/backup_$TIMESTAMP.tar.gz" /home/user 2> >(tee -a "$ERROR_LOG" >&2) | tee -a "$LOG_FILE"

# 检查错误
if [ -s "$ERROR_LOG" ]; then
    echo "Backup errors occurred, check $ERROR_LOG"
else
    echo "Backup completed, log in $LOG_FILE"
fi
加入 cron
crontab -e
添加任务
0 2 * * * /path/to/backup.sh
解释
  • 备份 /home/user,分离 stdout 和 stderr。
  • tee -a:追加日志。
  • 每天凌晨 2 点执行。
输出示例
  • LOG_FILE:

    home/user/file1.txt
    home/user/dir1
    home/user/file2.txt
    
  • ERROR_LOG(若有错误):

    tar: /home/user/restricted: Permission denied
    

🔗 结合其他工具

概述

tee 常与其他工具结合,增强功能。

与 grep 结合

ls -l | tee dir_list.txt | grep ".txt"
解释
  • 保存完整输出,过滤特定内容。

与 awk 结合

ps aux | tee ps_output.txt | awk '{print $1, $2}'
解释
  • 保存进程信息,提取字段。

与 sudo 结合

echo "data" | sudo tee /root/file.txt
解释
  • 写入受限文件。

与 cron 结合

0 0 * * * top -b -n 1 | tee -a /var/log/system_monitor.log
解释
  • 定时记录系统状态。

📝 总结

tee 是 Linux 中处理数据流的分流工具,通过从标准输入读取数据并同时写入文件和标准输出,提供了强大的日志记录和数据处理能力。

更多技术分享,关注公众号:halugin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值