#!/bin/sh set -eu INBOX="${INBOX:-/inbox}" DROP="${DROP:-/drop}" STABLE_FOR="${STABLE_FOR:-5}" # seconds with unchanged size to consider stable SCAN_FALLBACK="${SCAN_FALLBACK:-60}" # seconds between full scans (safety net) echo "[mover] Watching inbox ${INBOX} -> ${DROP} (stable for ${STABLE_FOR}s)" mkdir -p "$INBOX" "$DROP" is_stable() { f="$1" [ -f "$f" ] || return 1 size_a="$(stat -c%s "$f" 2>/dev/null || echo 0)" sleep "$STABLE_FOR" size_b="$(stat -c%s "$f" 2>/dev/null || echo 0)" [ "$size_a" -eq "$size_b" ] } move_file() { src="$1" [ -f "$src" ] || return 0 rel="${src#$INBOX/}" dest_dir="$DROP/$(dirname "$rel")" dest="$dest_dir/$(basename "$rel")" mkdir -p "$dest_dir" mv -f -- "$src" "$dest" echo "[mover] Moved $(basename "$src")" } process_one() { f="$1" [ -f "$f" ] || return 0 if is_stable "$f"; then move_file "$f" fi } scan_all() { find "$INBOX" -type f -size +0c -print0 | while IFS= read -r -d '' f; do process_one "$f" done } start_watcher() { if command -v inotifywait >/dev/null 2>&1; then echo "[mover] Starting inotify watcher" inotifywait -q -m -r -e close_write,moved_to,create --format '%w%f' "$INBOX" | \ while IFS= read -r path; do process_one "$path" done & echo "[mover] Watcher pid $!" else echo "[mover] inotifywait not available; relying on periodic scans" fi } start_watcher while :; do scan_all sleep "$SCAN_FALLBACK" done