fix: pos media sync — normalize trailing-slash source + surface find errors
This commit is contained in:
+40
-2
@@ -69,8 +69,26 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
[ "$MP3" -eq 1 ] || [ "$MP4" -eq 1 ] || { MP3=1; MP4=1; }
|
||||
|
||||
# Normalize a trailing slash on the source: GNU find strips it on the starting
|
||||
# point (find -H /x/ -type f emits /x/a.mp3, not /x//a.mp3), so with
|
||||
# SRC=/x/ the rel prefix "${f#"$SRC/"}" becomes /x// which never matches and
|
||||
# files would nest under <stick>/Music//x/... instead of mirroring the tree.
|
||||
# Covers both --source /x/ and MEDIA_SYNC_SOURCE=.../.
|
||||
SRC="${SRC%/}"
|
||||
[ -n "$SRC" ] || err "Source not found: $SRC"
|
||||
|
||||
[ -d "$SRC" ] || err "Source not found: $SRC"
|
||||
|
||||
# find -H follows only the command-line source symlink; symlinks INSIDE the
|
||||
# tree are never followed, so their targets silently never sync. Count them
|
||||
# (mindepth 1: a symlink source itself IS followed and must not count) and
|
||||
# surface the skip instead of leaving a partial mirror unexplained.
|
||||
inner_links="$(find -H "$SRC" -mindepth 1 -type l 2>/dev/null | wc -l)" || true
|
||||
inner_links="${inner_links// }"
|
||||
if [ "$inner_links" -gt 0 ]; then
|
||||
warn "${inner_links} symlink(s) inside the source are not followed (find -H) — their targets will not be synced"
|
||||
fi
|
||||
|
||||
trap 'notify_send "Music sync FAILED"' ERR
|
||||
|
||||
section "Music sync"
|
||||
@@ -112,6 +130,26 @@ if [ "$DRY_RUN" -eq 0 ]; then
|
||||
mkdir -p "$dest_root"
|
||||
space_path="$dest_root"
|
||||
fi
|
||||
# One find pass into a temp list, sorted once, shared by the space scan and
|
||||
# the copy loop so both see the identical file set (the old double find is
|
||||
# gone). The old process substitution swallowed find's exit code and stderr
|
||||
# (invisible to set -e / pipefail): an unreadable subdir made find exit 1
|
||||
# with "Permission denied" yet the tool still announced a false "Sync
|
||||
# complete" on a partial tree. Capture both and surface them explicitly
|
||||
# instead of continuing silently.
|
||||
find_list="$(mktemp)"
|
||||
find_err="$(mktemp)"
|
||||
trap 'rm -f "$find_list" "$find_err"' EXIT
|
||||
find_rc=0
|
||||
find -H "$SRC" "${find_expr[@]}" >"$find_list" 2>"$find_err" || find_rc=$?
|
||||
sort -o "$find_list" "$find_list"
|
||||
if [ "$find_rc" -ne 0 ] || [ -s "$find_err" ]; then
|
||||
warn "find of the source reported problems — results may be incomplete:"
|
||||
if [ -s "$find_err" ]; then
|
||||
sed 's/^/ /' "$find_err"
|
||||
fi
|
||||
fi
|
||||
|
||||
need_kb=0
|
||||
while IFS= read -r f; do
|
||||
rel="${f#"$SRC/"}"
|
||||
@@ -119,7 +157,7 @@ while IFS= read -r f; do
|
||||
sz="$(stat -c %s "$f" 2>/dev/null || printf 0)"
|
||||
need_kb=$((need_kb + (sz + 1023) / 1024))
|
||||
fi
|
||||
done < <(find -H "$SRC" "${find_expr[@]}")
|
||||
done < "$find_list"
|
||||
have_kb="$(df -Pk "$space_path" 2>/dev/null | awk 'NR==2 {print $4}')"
|
||||
have_kb="${have_kb:-0}"
|
||||
if [ "$need_kb" -gt "$have_kb" ]; then
|
||||
@@ -154,7 +192,7 @@ while IFS= read -r f; do
|
||||
else
|
||||
unchanged=$((unchanged + 1))
|
||||
fi
|
||||
done < <(find -H "$SRC" "${find_expr[@]}" | sort)
|
||||
done < "$find_list"
|
||||
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo "DRY RUN — nothing copied. Would sync: ${added} new, ${updated} updated, ${unchanged} unchanged → $dest_root"
|
||||
|
||||
Reference in New Issue
Block a user