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

CentOS7下GNU time输出重定向至文件丢失问题问询

问题原因
  1. /dev/stdout 并非实时流,它是指向当前进程stdout对应文件实体的符号链接。当脚本输出重定向到文件时,/dev/stdout会直接指向该文件。
  2. GNU time 使用--output=/dev/stdout时,会独立打开目标文件进行写入;而脚本的EXIT陷阱是通过bash已打开的stdout文件描述符写入内容。两者的文件指针操作不同步,陷阱的写入会直接覆盖或截断time的输出内容。
  3. 本质冲突:直接操作/dev/stdout文件实体,与通过bash的stdout流写入是两个独立的文件操作,指针位置不共享,导致time的输出被冲掉。
解决办法

方法1:文件描述符重定向(推荐)

放弃--output参数,利用GNU time默认输出到stderr的特性,通过文件描述符重定向将time的输出合并到程序的stdout,同时保留程序的stderr:

# 先设置环境变量
export YOUR_ENV_VAR=target_value

# 核心执行命令
{ /usr/bin/time -p program.exe 2>&1 1>&3; } 3>&1 2>&4

原理:

  • 用文件描述符3保存原stdout,4保存原stderr
  • 2>&1将time的输出(原本在stderr)重定向到原stdout
  • 1>&3将程序的stdout重定向到原stdout,确保程序输出与time记录流向同一目标
  • 程序的stderr仍保留原路径,仅输出关键警告/错误

方法2:临时文件中转输出

将time的输出先写入临时文件,脚本退出前再将临时文件内容追加到stdout,避开直接操作/dev/stdout的冲突:

# 设置环境变量
export YOUR_ENV_VAR=target_value

# 创建临时文件
time_log=$(mktemp)
# 退出陷阱:输出time记录并清理临时文件
trap 'cat "$time_log" >> /dev/stdout; rm -f "$time_log"' EXIT

# 执行程序,time输出写入临时文件
/usr/bin/time -p --output="$time_log" --append program.exe

原理:

  • 临时文件独立存储time的输出,不受陷阱函数对stdout的写入操作影响
  • EXIT陷阱在脚本退出前统一将临时文件内容追加到stdout,保证内容不丢失

方法3:调整陷阱写入行为(仅限简单场景)

如果必须保留--output=/dev/stdout,确保陷阱函数对stdout的写入为追加模式,且等待time执行完成后再触发:

# 设置环境变量
export YOUR_ENV_VAR=target_value

# 先执行time,等待子进程完成写入
/usr/bin/time -p --output="/dev/stdout" --append program.exe
# 陷阱用追加模式写入,避免覆盖
trap 'echo "脚本退出提示" >> /dev/stdout' EXIT

注意:

  • 此方法仅适用于脚本无后台进程的场景,否则陷阱可能在time写入完成前触发
  • 若陷阱输出内容较多,仍存在覆盖time输出的风险,可靠性不如前两种方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:53:09