如何监控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
使用说明
- 先安装依赖:
- Debian/Ubuntu系:
sudo apt install inotify-tools - RHEL/CentOS/Fedora系:
sudo dnf install inotify-tools
- Debian/Ubuntu系:
- 修改脚本开头的配置项,匹配你的实际路径和触发逻辑
- 给脚本加执行权限:
chmod +x sensor_monitor.sh - 直接运行测试,确认符合预期后可配置为systemd服务实现开机后台自启
可选调整项
- 如果你的两个传感器触发间隔非常短,可以把
MAX_INTERVAL调小到2-5秒,降低误触发概率 - 如果不需要防重复触发,可把
COOLDOWN设为0 - 如果不需要超时清理逻辑,删除
cleanup_expired_flags相关的代码即可,不影响核心功能
内容的提问来源于stack exchange,提问作者jody
相关产品推荐
相关产品推荐

