如何实现inotifywait命令的队列化执行?
让多文件触发的rclone移动任务按队列串行执行
原脚本的问题在于,每次inotifywait检测到文件完成写入后,会立刻启动一个独立的rclone move进程,当多个文件同时/陆续创建时,这些rclone任务会并行运行。要实现队列式的串行执行(一个任务完成再处理下一个),可以用**命名管道(FIFO)**来实现,它能天然保证任务的顺序性和串行处理。
改造后的完整脚本
#!/bin/bash # 目标监控目录 MONITOR_DIR="a specific folder" # 命名管道路径,用来存待处理的文件名 QUEUE_FILE="./rclone_queue" # 检查并创建命名管道,避免重复创建 if [ ! -p "$QUEUE_FILE" ]; then mkfifo "$QUEUE_FILE" fi # 启动后台进程:从队列读取文件名,串行执行rclone move # 这个进程会一直运行,直到脚本被终止 while read -r file; do # 确保文件存在(避免inotify触发后文件被提前删除的情况) if [ -f "$MONITOR_DIR/$file" ]; then echo "开始处理文件: $file" rclone move "$MONITOR_DIR/$file" … # 替换成你的rclone目标参数 echo "完成处理文件: $file" else echo "文件已不存在,跳过: $file" fi done < "$QUEUE_FILE" & # 记录后台进程PID,方便后续清理 QUEUE_PID=$! # 脚本退出时清理管道和后台进程 trap 'rm -f "$QUEUE_FILE"; kill $QUEUE_PID 2>/dev/null' EXIT # 进入监控目录,启动inotifywait检测文件关闭写入事件 cd "$MONITOR_DIR" || exit 1 inotifywait -me close_write --format %f . | while read -r file; do # 将文件名写入队列,管道会自动保证顺序 echo "$file" > "$QUEUE_FILE" done
核心逻辑说明
- 命名管道(FIFO):它是一种特殊的文件,写入的内容会按顺序保存,且同一时间只能有一个进程读取处理,天然实现了队列的串行特性。
- 后台处理进程:专门负责从队列读取文件名并执行rclone,这个进程会一直等待队列中的新任务,处理完一个才会取下一个。
- inotifywait触发逻辑:不再直接执行rclone,而是把检测到的文件名写入队列,这样不管同时触发多少文件,都会按顺序排队等待处理。
- 清理机制:用
trap命令在脚本退出时自动删除管道并终止后台进程,避免残留资源。
内容的提问来源于stack exchange,提问作者God of Money
相关产品推荐
相关产品推荐

