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

如何监控2个及以上文件/目录变更,仅当两者都修改时执行指定脚本

双路径变更联合触发监控方案

原脚本问题分析

原脚本的核心逻辑缺陷是串行阻塞等待:必须先触发第一个目录的变更,才会开始等待第二个目录的变更。如果第二个目录的变更发生在第一个之前,或者两次变更的时间差超出预期,会直接出现死等、漏触发、误触发的问题,完全无法满足需求。

实现思路

用双后台进程分别独立监控两个目标路径,监控到变更后写入对应状态标记,每次有变更事件时检查两个标记是否同时存在,同时存在则触发目标动作。额外增加超时清理逻辑,避免历史标记导致误触发,全程走内存存储标记实现近实时响应。

完整可运行实现

#!/bin/bash
# 配置项,请根据实际情况修改
# 支持监控目录或者单个文件
MONITOR_PATH1="/home/user/triggerdir"
MONITOR_PATH2="/home/user/triggerdir2"
# 触发后要执行的命令/脚本路径,可直接替换为你自己的脚本
TRIGGER_SCRIPT="echo Alert | mail -n -s 'test-notify SCRIPT HUZAAAA' user@gmail.com"
# 状态标记存内存文件系统,无磁盘IO延迟,性能更高
FLAG_DIR="/dev/shm/sensor_trigger_flags"
# 两个传感器变更的最大允许间隔,单位秒,超过则认为是两次独立事件,重置标记
MAX_INTERVAL=30
# 触发后冷却时间,避免同一次事件多次写入导致重复触发,单位秒
COOLDOWN=5

# 初始化环境
mkdir -p "$FLAG_DIR"
FLAG1="$FLAG_DIR/sensor1.flag"
FLAG2="$FLAG_DIR/sensor2.flag"
rm -f "$FLAG1" "$FLAG2"

# 脚本退出时自动清理后台进程和临时文件
cleanup() {
    kill ${MONITOR_PID1} ${MONITOR_PID2} ${CLEANUP_PID} 2>/dev/null
    rm -rf "$FLAG_DIR"
    exit 0
}
trap cleanup SIGINT SIGTERM SIGQUIT

# 检查是否满足触发条件
check_trigger() {
    if [ -f "$FLAG1" ] && [ -f "$FLAG2" ]; then
        # 两个标记都存在,触发目标动作
        rm -f "$FLAG1" "$FLAG2"
        eval "$TRIGGER_SCRIPT"
        # 冷却期避免重复触发
        sleep $COOLDOWN
    fi
}

# 监控第一个路径的后台进程
monitor1() {
    inotifywait -mq -e modify,close_write "$MONITOR_PATH1" | while read -r event; do
        touch "$FLAG1"
        check_trigger
    done
}

# 监控第二个路径的后台进程
monitor2() {
    inotifywait -mq -e modify,close_write "$MONITOR_PATH2" | while read -r event; do
        touch "$FLAG2"
        check_trigger
    done
}

# 超时标记清理后台进程,避免历史标记误触发
cleanup_expired_flags() {
    while true; do
        current_time=$(date +%s)
        for flag in "$FLAG1" "$FLAG2"; do
            if [ -f "$flag" ]; then
                flag_time=$(stat -c %Y "$flag")
                if [ $((current_time - flag_time)) -gt $MAX_INTERVAL ]; then
                    rm -f "$flag"
                fi
            fi
        done
        sleep 1
    done
}

# 启动所有后台进程
monitor1 &
MONITOR_PID1=$!
monitor2 &
MONITOR_PID2=$!
cleanup_expired_flags &
CLEANUP_PID=$!

# 保持主进程运行
wait

使用说明

  1. 先安装依赖:
    • Debian/Ubuntu系:sudo apt install inotify-tools
    • RHEL/CentOS/Fedora系:sudo dnf install inotify-tools
  2. 修改脚本开头的配置项,匹配你的实际路径和触发逻辑
  3. 给脚本加执行权限:chmod +x sensor_monitor.sh
  4. 直接运行测试,确认符合预期后可配置为systemd服务实现开机后台自启

可选调整项

  • 如果你的两个传感器触发间隔非常短,可以把MAX_INTERVAL调小到2-5秒,降低误触发概率
  • 如果不需要防重复触发,可把COOLDOWN设为0
  • 如果不需要超时清理逻辑,删除cleanup_expired_flags相关的代码即可,不影响核心功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 14:18:02