如何编写Bash脚本检测执行命令后指定目录是否有新文件生成
问题根因
你原脚本和对比逻辑存在2个核心错误,导致无法正确判断文件变化:
- 变量赋值语法错误:
FILES_BEFORE= ls $WATCH_DIR写法中等号两侧不能有空格,且捕获命令输出需要用$()包裹命令,正确写法为FILES_BEFORE=$(ls "$WATCH_DIR") - 变量调用逻辑错误:
$FILES_AFTER |sort是把变量存储的文件名当成命令执行,而非把文件列表内容传给sort,正确写法为echo "$FILES_AFTER" | sort
实现方案
方案1:兼容所有POSIX环境的文件列表对比法
适合短时间运行的命令监控,执行完命令后对比前后文件列表即可:
#!/bin/bash # 定义监控目录 WATCH_DIR=./tmp # 确保监控目录存在 mkdir -p "$WATCH_DIR" # 捕获初始文件列表,-A参数可包含隐藏文件,不需要可删除 FILES_BEFORE=$(ls -A "$WATCH_DIR") # ------------------- # 这里替换为你要运行的业务命令,下方为模拟创建文件的测试代码 echo > "$WATCH_DIR/filename" # ------------------- # 捕获命令运行后的文件列表 FILES_AFTER=$(ls -A "$WATCH_DIR") # 方案A:只要目录有任何文件新增/删除/改名,就退出 if [ "$FILES_BEFORE" != "$FILES_AFTER" ]; then echo "检测到目录文件变化,退出程序" exit 1 fi # 方案B:只检测新增文件时用下面的逻辑,不需要可以删除 if diff <(echo "$FILES_BEFORE" | sort) <(echo "$FILES_AFTER" | sort) | grep -q '^>'; then echo "检测到新文件创建,退出程序" exit 1 fi # 无变化时继续执行后续逻辑 echo "目录无变化,继续运行"
你之前写的三个对比方法修正后也可正常使用,比如修正后的comm判断逻辑:
# 判断是否有新增文件 NEW_FILES=$(comm -23 <(echo "$FILES_AFTER" | sort) <(echo "$FILES_BEFORE" | sort)) if [ -n "$NEW_FILES" ]; then echo "检测到新文件:$NEW_FILES,退出程序" exit 1 fi
方案2:Linux环境下实时监控法
适合长时间运行的命令监控,不需要等命令执行完就能实时检测新文件,需要先安装inotify-tools工具包:
- Debian/Ubuntu系安装命令:
apt install inotify-tools - RHEL/CentOS系安装命令:
yum install inotify-tools
实现代码:
#!/bin/bash WATCH_DIR=./tmp mkdir -p "$WATCH_DIR" # 后台启动inotify监控,检测到新文件创建就终止主程序 { inotifywait -m -e create "$WATCH_DIR" | while read -r dir events filename; do echo "检测到新文件创建:$filename,即将退出" kill $$ exit 0 done } & WATCH_PID=$! # ------------------- # 这里替换为你要运行的业务命令,下方为模拟长时间运行任务的测试代码 sleep 10 # ------------------- # 业务命令正常执行完,关闭后台监控后正常退出 kill $WATCH_PID echo "任务执行完成,无新文件创建" exit 0
内容的提问来源于stack exchange,提问作者Süleyman Sümertaş
相关产品推荐
相关产品推荐

