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

如何用Shell常用工具实现带时间戳记录的输出监控程序?

用Shell工具实现二进制输出监控与时间戳记录

完全可以用Shell常用工具(bash、dd、date、sleep)实现这个需求,以下是具体解决方案:

核心逻辑

  • 透明转发应用的二进制输出到stdout,同时监控输出状态
  • 首次收到输出时记录起始时间戳,启动后台定时器验证是否持续输出满3秒,满足则写入日志
  • 每次收到新输出时重置静默定时器,当静默超过5秒时记录结束时间戳
  • 用陷阱处理确保脚本退出时清理后台进程,避免残留

监控脚本实现

保存以下内容为monitor脚本,赋予执行权限:

#!/bin/bash

# 可配置参数
MIN_ACTIVE=3       # 触发记录的最小持续输出时长(秒)
SILENCE_THRESH=5   # 判定输出结束的静默时长(秒)
LOG_DEST="${MONITOR_LOG:-/dev/stderr}"  # 日志输出位置,默认stderr,可通过环境变量指定

# 状态追踪变量
start_epoch=""
timer_pid=""

# 退出清理函数
cleanup() {
    [ -n "$timer_pid" ] && kill "$timer_pid" 2>/dev/null
    # 若存在未收尾的输出周期,补录结束时间
    [ -n "$start_epoch" ] && echo "End: $(date +'%d.%m - %H:%M:%S')" >> "$LOG_DEST"
    exit 0
}

# 绑定退出信号处理
trap cleanup EXIT INT TERM

# 主循环:持续读取并转发输入
while true; do
    # 读取二进制数据块(1k大小可根据实际调整)
    block=$(dd bs=1k count=1 2>/dev/null || true)
    
    if [ -n "$block" ]; then
        # 转发数据到stdout,确保二进制内容不被篡改
        printf "%s" "$block"

        if [ -z "$start_epoch" ]; then
            # 首次收到输出,记录起始时间戳的epoch值
            start_epoch=$(date +'%s')
            # 启动后台定时器:验证是否持续输出满MIN_ACTIVE秒
            (
                sleep "$MIN_ACTIVE"
                # 若start_epoch仍存在,说明输出持续足够久,写入开始日志
                [ -n "$start_epoch" ] && echo "Start: $(date -d "@$start_epoch" +'%d.%m - %H:%M:%S')" >> "$LOG_DEST"
            ) &
            timer_pid=$!
        else
            # 已有活跃周期,先杀掉之前的静默定时器
            [ -n "$timer_pid" ] && kill "$timer_pid" 2>/dev/null
        fi

        # 启动新的静默定时器:检测是否超过SILENCE_THRESH秒无输出
        (
            sleep "$SILENCE_THRESH"
            # 若start_epoch仍存在,说明已静默足够久,写入结束日志并重置状态
            if [ -n "$start_epoch" ]; then
                echo "End: $(date +'%d.%m - %H:%M:%S')" >> "$LOG_DEST"
                start_epoch=""
            fi
        ) &
        timer_pid=$!
    else
        # 无输入时短暂休眠,避免空循环占用CPU
        sleep 0.1
    fi
done

使用方法

  1. 给脚本添加执行权限:
    chmod +x monitor
    
  2. 按需求调用(日志默认输出到stderr):
    app | ./monitor > out
    
  3. 若要将日志输出到指定文件,设置环境变量:
    MONITOR_LOG=output.log app | ./monitor > out
    

关键细节说明

  • 使用dd读取二进制数据块,避免read命令的文本行限制,确保二进制内容完整转发
  • 用date +'%s'记录起始时间的epoch值,确保后续生成的开始时间戳是实际输出启动的时刻,而非满足3秒后的时间
  • 后台定时器用子进程实现,通过kill命令重置定时器,确保5秒内的新输出被视为同一周期
  • 陷阱处理EXIT、INT、TERM信号,确保脚本退出时清理后台进程,同时补录未结束的输出周期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 12:43:33