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

Linux下监控多minicom日志文件,触发脚本遇fswatch循环问题求助

监控多串口日志文件,仅在完整数据包写入时触发脚本

场景说明

  • Linux系统运行4个minicom实例,分别读取4台设备的串口数据,日志保存到对应文本文件中
  • 物理事件触发的数据包格式如下:
[timestamp] header
[timestamp] data
...
[timestamp] data
[timestamp] footer

[timestamp] header
...

核心需求

监控4个日志文件,仅当文件被修改且末尾出现footer行时,运行指定脚本

之前尝试遇到的问题

  1. 串口数据行速率约6~7毫秒/行,不希望每新增一行就触发通知,仅需每个完整数据包触发一次
  2. 每个数据包的行数(耗时)随机,无法通过固定fswatch的latency参数实现单包单通知

失败的尝试方案

方案1:fswatch触发后检查最后一行

用fswatch监控文件,每次触发后执行tail -n 1 logfile对比footer,但无法解决频繁触发的问题

方案2:fswatch + 脚本检测

执行命令:

fswatch -0 logfile.log | xargs -0 -I {} script.sh

配套script.sh代码:

#!/bin/sh
footer='packet end'
newline=$(tail -n 1 $HOME/slave.log | grep "$footer")
if [ "$newline" != "" ];
then
    echo "found"
fi

问题:一旦日志末尾是footer行,fswatch会持续触发通知,导致脚本无限循环打印"found"

可行解决方案

核心思路

跟踪每个日志文件已处理的行号,每次监控触发时仅检查新增行,找到footer后更新行号,避免重复触发。

单文件监控脚本示例

#!/bin/bash

LOG_FILE="$HOME/slave.log"
LAST_LINE_FILE="$HOME/slave.log.lastline"
FOOTER='packet end'
TARGET_SCRIPT='/path/to/your/target/script.sh'

# 初始化行号记录文件
if [ ! -f "$LAST_LINE_FILE" ]; then
    wc -l "$LOG_FILE" | awk '{print $1}' > "$LAST_LINE_FILE"
fi

while true; do
    # 监听文件修改事件
    inotifywait -q -e modify "$LOG_FILE"

    # 获取当前总行数与已处理行号
    current_lines=$(wc -l "$LOG_FILE" | awk '{print $1}')
    last_lines=$(cat "$LAST_LINE_FILE")

    # 检查新增行中是否包含footer
    if [ "$current_lines" -gt "$last_lines" ]; then
        tail -n $((current_lines - last_lines)) "$LOG_FILE" | grep -q "$FOOTER"
        if [ $? -eq 0 ]; then
            # 执行目标脚本
            "$TARGET_SCRIPT"
            # 更新已处理行号
            echo "$current_lines" > "$LAST_LINE_FILE"
        fi
    fi
done

多文件扩展方案

将监控逻辑封装为函数,为4个日志文件分别启动后台监控进程:

#!/bin/bash

monitor_log() {
    local LOG_FILE="$1"
    local LAST_LINE_FILE="${LOG_FILE}.lastline"
    local FOOTER="$2"
    local TARGET_SCRIPT="$3"

    # 初始化行号记录
    if [ ! -f "$LAST_LINE_FILE" ]; then
        wc -l "$LOG_FILE" | awk '{print $1}' > "$LAST_LINE_FILE"
    fi

    while true; do
        inotifywait -q -e modify "$LOG_FILE"
        current_lines=$(wc -l "$LOG_FILE" | awk '{print $1}')
        last_lines=$(cat "$LAST_LINE_FILE")

        if [ "$current_lines" -gt "$last_lines" ]; then
            tail -n $((current_lines - last_lines)) "$LOG_FILE" | grep -q "$FOOTER"
            if [ $? -eq 0 ]; then
                "$TARGET_SCRIPT" "$LOG_FILE"  # 可将日志路径传给目标脚本
                echo "$current_lines" > "$LAST_LINE_FILE"
            fi
        fi
    done
}

# 启动4个后台监控进程
monitor_log "/path/to/log1.log" "packet end" "/path/to/target.sh" &
monitor_log "/path/to/log2.log" "packet end" "/path/to/target.sh" &
monitor_log "/path/to/log3.log" "packet end" "/path/to/target.sh" &
monitor_log "/path/to/log4.log" "packet end" "/path/to/target.sh" &

wait

方案优势

  • 用inotifywait精准监听文件修改,避免fswatch的重复触发问题
  • 通过行号记录,仅处理新增内容,不会重复检测已处理过的footer
  • 适配数据包行数随机的场景,只要新增行中出现footer就触发一次脚本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:40:34