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

如何在Bash中监控标准输出每行作为最后输出行的时长用于基准测试?

捕获标准输出每行的持续时间并格式化输出

刚好遇到过类似的需求,不用修改原程序,通过管道配合awk就能完美解决。直接上解决方案,再给你拆解逻辑:

完整实现命令

针对你给出的测试脚本,运行这个命令就能得到想要的结果:

(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2) | awk '
{
    # 存储每行内容和对应的精确时间戳(含毫秒)
    lines[NR] = $0
    times[NR] = systime() + (substr(strftime("%N"), 1, 6)/1000000)
}
END {
    # 记录程序结束的时间戳
    end_time = systime() + (substr(strftime("%N"), 1, 6)/1000000)
    # 遍历所有行计算时长
    for (i=1; i<=NR; i++) {
        if (i < NR) {
            # 非最后一行:时长 = 下一行输出时间 - 当前行输出时间
            duration = times[i+1] - times[i]
        } else {
            # 最后一行:时长 = 程序结束时间 - 当前行输出时间
            duration = end_time - times[i]
        }
        # 格式化输出,保留两位小数
        printf "%.2f %s ", duration, lines[i]
    }
    # 最后补一个换行,让输出更整洁
    print ""
}
'

运行后会输出:1.00 a 3.00 b 2.00 c (末尾的小空格不影响使用,介意的话可以用数组收集结果后再拼接输出)

适配实际场景(比如QEMU)

把上面命令里的测试脚本(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)换成你的QEMU命令就行,比如:

qemu-system-x86_64 your_args_here | awk '...' # 这里的awk脚本和上面完全一样

注意事项

  1. 输出缓冲问题:如果原程序用了全缓冲(而非行缓冲),会导致多行输出一次性被awk读取,时间差会变成0。这种情况可以用stdbuf强制行缓冲:

    stdbuf -oL qemu-system-x86_64 your_args_here | awk '...'
    

    -oL参数会让标准输出以行缓冲模式工作,确保每行输出都会立即被awk捕获。

  2. 时间精度调整:上面的脚本用了毫秒级精度,如果需要更高精度(比如微秒),可以把时间戳的计算改成:

    times[NR] = systime() + (substr(strftime("%N"), 1, 9)/1000000000)
    

    对应的输出格式也可以改成%.6f来保留六位小数。

内容的提问来源于stack exchange,提问作者Ciro Santilli OurBigBook.com

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:07:08