You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次调用exec日志重定向后如何重置避免旧日志重复写入

问题描述

在同一Bash脚本中多次执行exec > >(tee -a "${logFile}") 2>&1并指定不同日志文件时,较早的日志文件会被重复追加内容。示例脚本执行后:

  • test1.log包含三次输出:hello 1、hello 2、hello 3
  • test2.log包含后两次输出:hello 2、hello 3
  • test3.log仅包含最后一次输出:hello 3

如何在调用该exec命令前重置exec,让每个日志文件只记录对应阶段的输出?

示例脚本及执行结果:

$ cat sample.bash 
#!/bin/bash -e

function redirectOutputToLogFile()
{
    local -r logFile="${1}"

    mkdir -p "$(dirname "${logFile}")"
    exec > >(tee -a "${logFile}") 2>&1
}

function main()
{
    redirectOutputToLogFile 'test1.log'
    echo 'hello 1'

    redirectOutputToLogFile 'test2.log'
    echo 'hello 2'

    redirectOutputToLogFile 'test3.log'
    echo 'hello 3'
}

main "${@}"

执行结果:

$ ./sample.bash 
hello 1
hello 2
hello 3

$ cat test1.log 
hello 1
hello 2
hello 3

$ cat test2.log 
hello 2
hello 3

$ cat test3.log 
hello 3
原因分析

每次执行exec > >(tee ...)时,是在当前标准输出的基础上新增重定向链路,而非替换原有链路。第一次执行后,stdout被指向test1.log的tee进程;第二次执行时,新的tee进程会接管stdout,但旧的test1.log的tee进程并未关闭,仍会持续接收后续输出,导致所有之前打开的日志文件都会被写入后续内容。

解决方案

核心思路是:在每次重定向前,先将stdout和stderr恢复到脚本初始的终端输出状态,再重新绑定到新的日志文件。具体通过保存原始文件描述符实现:

修改后的脚本如下:

#!/bin/bash -e

# 保存原始stdout(1)到描述符3,原始stderr(2)到描述符4
exec 3>&1 4>&2

function redirectOutputToLogFile()
{
    local -r logFile="${1}"

    # 先恢复stdout和stderr到原始状态
    exec >&3 2>&4

    mkdir -p "$(dirname "${logFile}")"
    # 重新定向到新日志文件
    exec > >(tee -a "${logFile}") 2>&1
}

function main()
{
    redirectOutputToLogFile 'test1.log'
    echo 'hello 1'

    redirectOutputToLogFile 'test2.log'
    echo 'hello 2'

    redirectOutputToLogFile 'test3.log'
    echo 'hello 3'

    # 脚本结束前恢复原始输出并关闭保存的描述符(可选)
    exec >&3 2>&4
    exec 3>&- 4>&-
}

main "${@}"
验证结果

修改后执行脚本,日志文件内容符合预期:

  • test1.log仅包含:hello 1
  • test2.log仅包含:hello 2
  • test3.log仅包含:hello 3
原理说明
  1. exec 3>&1 4>&2:将脚本启动时的终端输出通道(stdout/stderr)复制到备用描述符3和4,留存原始输出路径。
  2. exec >&3 2>&4:将当前stdout/stderr恢复为备用描述符指向的原始通道,此时之前的tee进程会因管道关闭而退出,停止接收后续输出。
  3. 每次重定向前执行恢复操作,确保新的exec > >(tee ...)仅将输出绑定到当前日志文件,不会影响历史日志。

内容的提问来源于stack exchange,提问作者Nam Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:51:05