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

如何让STDOUT、STDERR同时输出到终端与日志并保留二者区分

问题描述

这是关于「如何让STDOUT和STDERR同时输出到终端与日志文件」的后续提问,核心需求如下:

  • 运行命令时,需将STDOUT和STDERR存入同一个日志文件,严格保留输出的时序关联
  • 必须确保STDERR仍输出到原本的STDERR流(不能混到STDOUT中)
  • 要保留STDOUT与STDERR的流区分,同时保留原命令的返回码

动机

部分工具会区分处理STDOUT和STDERR,比如给STDERR内容着色,或在命令返回非零值时专门展示STDERR内容,因此需要满足上述需求。期望能通过类似如下的命令调用实现:

log-output --file=command.log -c "make stuff-with-stderr"

现有方案的不足

尝试过两种方法,但均无法满足需求:

  1. 分文件存储的tee方案
the_cmd 1> >(tee stdout.txt ) 2> >(tee stderr.txt >&2 )
  • 缺点:STDOUT和STDERR分别存入不同文件,丢失时序关联;且最终两者都只输出到STDOUT流,破坏了原流的区分属性。
  1. script命令方案
script -e -B build.log -c "the_cmd"
  • 缺点:虽然将两者存入同一文件并保留时序,但所有输出都被重定向到STDOUT,丢失了STDERR的原流属性。

请问是否有其他可行方案?


可行解决方案

方法一:自定义bash脚本实现log-output功能

可以写一个简单的bash脚本,完全实现你想要的log-output命令:

#!/bin/bash

# 解析输入参数
while [[ $# -gt 0 ]]; do
    case "$1" in
        --file=*)
            LOG_FILE="${1#*=}"
            shift
            ;;
        -c)
            CMD="$2"
            shift 2
            ;;
        *)
            echo "未知参数: $1" >&2
            exit 1
            ;;
    esac
done

# 保存原STDOUT和STDERR的文件描述符
exec 3>&1 4>&2

# 捕获命令输出,分流写入日志并保留原流属性
{
    bash -c "$CMD" 2>&1 1>&3 | tee -a "$LOG_FILE" >&4
} 3>&1 1>&2 | tee -a "$LOG_FILE"

# 关闭临时文件描述符
exec 3>&- 4>&-

# 保留原命令的返回码
EXIT_CODE=${PIPESTATUS[1]}
exit $EXIT_CODE

将脚本保存为log-output,赋予执行权限(chmod +x log-output),即可按期望调用:

./log-output --file=command.log -c "make stuff-with-stderr"
  • 核心逻辑:通过临时文件描述符保存原流,将STDERR和STDOUT分别捕获后,用tee写入同一个日志文件,同时把各自内容送回原流,既保留时序又不破坏流区分,还能获取原命令的返回码。

方法二:单命令行实现(无需脚本)

如果不想单独写脚本,可以直接用一行命令实现等效效果:

cmd="make stuff-with-stderr"; { $cmd 2>&1 1>&3 | tee -a command.log >&2; } 3>&1 1>&2 | tee -a command.log; exit ${PIPESTATUS[1]}
  • 说明:用文件描述符3临时保存原STDOUT,先将STDERR转成STDOUT后写入日志并转回原STDERR流;再将原STDOUT内容写入日志,最后通过PIPESTATUS获取原命令的返回码。

验证要点

  • 日志文件command.log会包含STDOUT和STDERR的完整内容,时序与终端输出完全一致
  • 终端上STDERR内容仍输出到原STDERR流,支持工具的着色、特殊处理等逻辑
  • 执行完命令后,用echo $?可查看原命令的返回码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:50:16