如何实时遍历目录?解决Bash脚本并发时的文件变更报错问题
用while循环动态处理XML文件的解决方案
完全可以用while循环替代for循环,解决文件动态变化(修改/删除/新增)以及多进程并发处理的问题。for循环会一次性读取所有匹配的文件列表,之后不管目录内文件如何变化都只会遍历这个固定列表;而while循环可以每次迭代都重新扫描目录,获取最新的文件状态,同时配合原子操作还能避免多进程抢文件的冲突。
核心实现思路
- 每次循环重新扫描目标目录,获取待处理的XML文件
- 用原子重命名操作锁定文件(Linux下同文件系统的
mv是原子操作),确保同一时间只有一个进程能处理该文件 - 处理完成后删除文件,避免重复处理
示例脚本
#!/bin/bash TARGET_DIR="./folder" while true; do # 每次迭代重新查找第一个XML文件 xml_file=$(find "$TARGET_DIR" -maxdepth 1 -type f -name "*.xml" | head -n 1) # 没有文件时退出,若要持续监听可替换为sleep后继续 if [ -z "$xml_file" ]; then echo "无待处理XML文件,退出脚本" break # sleep 5 # continue fi # 原子重命名锁定文件,防止多进程争抢 temp_file="$TARGET_DIR/.processing_$(basename "$xml_file")" if mv "$xml_file" "$temp_file"; then # 执行你的导入逻辑,替换为实际命令 echo "正在处理文件: $temp_file" # your_import_command "$temp_file" # 处理完成后删除文件 rm "$temp_file" else # 文件已被其他进程抢先锁定,跳过当前迭代 continue fi done
关键细节说明
- 动态扫描:
find命令在每次循环都会重新遍历目录,确保拿到最新的文件列表,不会遗漏新增文件,也不会处理已被删除的文件 - 原子锁定:
mv操作是原子的,多个进程同时尝试移动同一个文件时,只有一个进程能成功,彻底避免了多进程重复处理同一文件的问题 - 持续监听:如果需要脚本一直运行等待新文件(比如目录会持续新增XML),可以把
break换成sleep 5; continue,让脚本每隔5秒重新扫描一次
内容的提问来源于stack exchange,提问作者dominikweber
相关产品推荐
相关产品推荐

